Blame tests/check_sonmp.c

Packit e9ba0d
/* -*- mode: c; c-file-style: "openbsd" -*- */
Packit e9ba0d
/*
Packit e9ba0d
 * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx>
Packit e9ba0d
 *
Packit e9ba0d
 * Permission to use, copy, modify, and/or distribute this software for any
Packit e9ba0d
 * purpose with or without fee is hereby granted, provided that the above
Packit e9ba0d
 * copyright notice and this permission notice appear in all copies.
Packit e9ba0d
 *
Packit e9ba0d
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
Packit e9ba0d
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
Packit e9ba0d
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
Packit e9ba0d
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
Packit e9ba0d
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
Packit e9ba0d
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Packit e9ba0d
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Packit e9ba0d
 */
Packit e9ba0d
Packit e9ba0d
#include <stdlib.h>
Packit e9ba0d
#include <sys/socket.h>
Packit e9ba0d
#include <arpa/inet.h>
Packit e9ba0d
#include <netinet/in.h>
Packit e9ba0d
#include <check.h>
Packit e9ba0d
#include "common.h"
Packit e9ba0d
Packit e9ba0d
char filenameprefix[] = "sonmp_send";
Packit e9ba0d
Packit e9ba0d
#ifdef ENABLE_SONMP
Packit e9ba0d
Packit e9ba0d
START_TEST (test_send_sonmp)
Packit e9ba0d
{
Packit e9ba0d
	int n;
Packit e9ba0d
	/* Packet we should build:
Packit e9ba0d
IEEE 802.3 Ethernet 
Packit e9ba0d
    Destination: Bay-Networks-(Synoptics)-autodiscovery (01:00:81:00:01:00)
Packit e9ba0d
    Source: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad)
Packit e9ba0d
    Length: 22
Packit e9ba0d
Logical-Link Control
Packit e9ba0d
    DSAP: SNAP (0xaa)
Packit e9ba0d
    IG Bit: Individual
Packit e9ba0d
    SSAP: SNAP (0xaa)
Packit e9ba0d
    CR Bit: Command
Packit e9ba0d
    Control field: U, func=UI (0x03)
Packit e9ba0d
        000. 00.. = Command: Unnumbered Information (0x00)
Packit e9ba0d
        .... ..11 = Frame type: Unnumbered frame (0x03)
Packit e9ba0d
    Organization Code: Nortel Networks SONMP (0x000081)
Packit e9ba0d
    PID: SONMP segment hello (0x01a2)
Packit e9ba0d
Nortel Networks / SynOptics Network Management Protocol
Packit e9ba0d
    NMM IP address: 172.17.142.37 (172.17.142.37)
Packit e9ba0d
    Segment Identifier: 0x000004
Packit e9ba0d
    Chassis type: Unknown (1)
Packit e9ba0d
    Backplane type: ethernet, fast ethernet and gigabit ethernet (12)
Packit e9ba0d
    NMM state: New (3)
Packit e9ba0d
    Number of links: 1
Packit e9ba0d
Packit e9ba0d
IEEE 802.3 Ethernet 
Packit e9ba0d
    Destination: Bay-Networks-(Synoptics)-autodiscovery (01:00:81:00:01:01)
Packit e9ba0d
    Source: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad)
Packit e9ba0d
    Length: 22
Packit e9ba0d
Logical-Link Control
Packit e9ba0d
    DSAP: SNAP (0xaa)
Packit e9ba0d
    IG Bit: Individual
Packit e9ba0d
    SSAP: SNAP (0xaa)
Packit e9ba0d
    CR Bit: Command
Packit e9ba0d
    Control field: U, func=UI (0x03)
Packit e9ba0d
        000. 00.. = Command: Unnumbered Information (0x00)
Packit e9ba0d
        .... ..11 = Frame type: Unnumbered frame (0x03)
Packit e9ba0d
    Organization Code: Nortel Networks SONMP (0x000081)
Packit e9ba0d
    PID: SONMP flatnet hello (0x01a1)
Packit e9ba0d
Nortel Networks / SynOptics Network Management Protocol
Packit e9ba0d
    NMM IP address: 172.17.142.37 (172.17.142.37)
Packit e9ba0d
    Segment Identifier: 0x000004
Packit e9ba0d
    Chassis type: Unknown (1)
Packit e9ba0d
    Backplane type: ethernet, fast ethernet and gigabit ethernet (12)
Packit e9ba0d
    NMM state: New (3)
Packit e9ba0d
    Number of links: 1
Packit e9ba0d
	*/
Packit e9ba0d
	char pkt1[] = {
Packit e9ba0d
		0x01, 0x00, 0x81, 0x00, 0x01, 0x00, 0x5e, 0x10,
Packit e9ba0d
		0x8e, 0xe7, 0x84, 0xad, 0x00, 0x16, 0xaa, 0xaa,
Packit e9ba0d
		0x03, 0x00, 0x00, 0x81, 0x01, 0xa2, 0xac, 0x11,
Packit e9ba0d
		0x8e, 0x25, 0x00, 0x00, 0x04, 0x01, 0x0c, 0x03,
Packit e9ba0d
		0x01 };
Packit e9ba0d
	char pkt2[] = {
Packit e9ba0d
		0x01, 0x00, 0x81, 0x00, 0x01, 0x01, 0x5e, 0x10,
Packit e9ba0d
		0x8e, 0xe7, 0x84, 0xad, 0x00, 0x16, 0xaa, 0xaa,
Packit e9ba0d
		0x03, 0x00, 0x00, 0x81, 0x01, 0xa1, 0xac, 0x11,
Packit e9ba0d
		0x8e, 0x25, 0x00, 0x00, 0x04, 0x01, 0x0c, 0x03,
Packit e9ba0d
		0x01 };
Packit e9ba0d
	struct packet *pkt;
Packit e9ba0d
	in_addr_t addr;	
Packit e9ba0d
	struct lldpd_mgmt *mgmt;
Packit e9ba0d
Packit e9ba0d
	/* Populate port and chassis */
Packit e9ba0d
	hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME;
Packit e9ba0d
	hardware.h_lport.p_id = "Not used";
Packit e9ba0d
	hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id);
Packit e9ba0d
	chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
Packit e9ba0d
	chassis.c_id = macaddress;
Packit e9ba0d
	chassis.c_id_len = ETHER_ADDR_LEN;
Packit e9ba0d
	TAILQ_INIT(&chassis.c_mgmt);
Packit e9ba0d
	addr = inet_addr("172.17.142.37");
Packit e9ba0d
	mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, 
Packit e9ba0d
				&addr, sizeof(in_addr_t), 0);
Packit e9ba0d
	if (mgmt == NULL)
Packit e9ba0d
		ck_abort();
Packit e9ba0d
	TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt, m_entries);
Packit e9ba0d
Packit e9ba0d
	/* Build packet */
Packit e9ba0d
	n = sonmp_send(NULL, &hardware);
Packit e9ba0d
	if (n != 0) {
Packit e9ba0d
		fail("unable to build packet");
Packit e9ba0d
		return;
Packit e9ba0d
	}
Packit e9ba0d
	if (TAILQ_EMPTY(&pkts)) {
Packit e9ba0d
		fail("no packets sent");
Packit e9ba0d
		return;
Packit e9ba0d
	}
Packit e9ba0d
	pkt = TAILQ_FIRST(&pkts);
Packit e9ba0d
	ck_assert_int_eq(pkt->size, sizeof(pkt1));
Packit e9ba0d
	fail_unless(memcmp(pkt->data, pkt1, sizeof(pkt1)) == 0);
Packit e9ba0d
	pkt = TAILQ_NEXT(pkt, next);
Packit e9ba0d
	if (!pkt) {
Packit e9ba0d
		fail("need one more packet");
Packit e9ba0d
		return;
Packit e9ba0d
	}
Packit e9ba0d
	ck_assert_int_eq(pkt->size, sizeof(pkt2));
Packit e9ba0d
	fail_unless(memcmp(pkt->data, pkt2, sizeof(pkt2)) == 0);
Packit e9ba0d
	fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than two packets sent");
Packit e9ba0d
}
Packit e9ba0d
END_TEST
Packit e9ba0d
Packit e9ba0d
START_TEST (test_recv_sonmp)
Packit e9ba0d
{
Packit e9ba0d
	char pkt1[] = {
Packit e9ba0d
		0x01, 0x00, 0x81, 0x00, 0x01, 0x00, 0x00, 0x1b,
Packit e9ba0d
		0x25, 0x08, 0x50, 0x47, 0x00, 0x13, 0xaa, 0xaa,
Packit e9ba0d
		0x03, 0x00, 0x00, 0x81, 0x01, 0xa2, 0xac, 0x10,
Packit e9ba0d
		0x65, 0xa8, 0x00, 0x02, 0x08, 0x38, 0x0c, 0x02,
Packit e9ba0d
		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit e9ba0d
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit e9ba0d
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit e9ba0d
		0x00, 0x00, 0x00, 0x00 };
Packit e9ba0d
	/* This is:
Packit e9ba0d
IEEE 802.3 Ethernet 
Packit e9ba0d
    Destination: Bay-Networks-(Synoptics)-autodiscovery (01:00:81:00:01:00)
Packit e9ba0d
    Source: Nortel_08:50:47 (00:1b:25:08:50:47)
Packit e9ba0d
    Length: 19
Packit e9ba0d
    Trailer: 000000000000000000000000000000000000000000000000...
Packit e9ba0d
Logical-Link Control
Packit e9ba0d
    DSAP: SNAP (0xaa)
Packit e9ba0d
    IG Bit: Individual
Packit e9ba0d
    SSAP: SNAP (0xaa)
Packit e9ba0d
    CR Bit: Command
Packit e9ba0d
    Control field: U, func=UI (0x03)
Packit e9ba0d
        000. 00.. = Command: Unnumbered Information (0x00)
Packit e9ba0d
        .... ..11 = Frame type: Unnumbered frame (0x03)
Packit e9ba0d
    Organization Code: Nortel Networks SONMP (0x000081)
Packit e9ba0d
    PID: SONMP segment hello (0x01a2)
Packit e9ba0d
Nortel Networks / SynOptics Network Management Protocol
Packit e9ba0d
    NMM IP address: 172.16.101.168 (172.16.101.168)
Packit e9ba0d
    Segment Identifier: 0x000208
Packit e9ba0d
    Chassis type: Accelar 8610 L3 switch (56)
Packit e9ba0d
    Backplane type: ethernet, fast ethernet and gigabit ethernet (12)
Packit e9ba0d
    NMM state: Heartbeat (2)
Packit e9ba0d
    Number of links: 1
Packit e9ba0d
	*/
Packit e9ba0d
	struct lldpd_chassis *nchassis = NULL;
Packit e9ba0d
	struct lldpd_port *nport = NULL;
Packit e9ba0d
	char cid[5];
Packit e9ba0d
	in_addr_t ip;
Packit e9ba0d
Packit e9ba0d
	fail_unless(sonmp_decode(NULL, pkt1, sizeof(pkt1), &hardware,
Packit e9ba0d
		&nchassis, &nport) != -1);
Packit e9ba0d
	if (!nchassis || !nport) {
Packit e9ba0d
		fail("unable to decode packet");
Packit e9ba0d
		return;
Packit e9ba0d
	}
Packit e9ba0d
	ck_assert_int_eq(nchassis->c_id_subtype,
Packit e9ba0d
	    LLDP_CHASSISID_SUBTYPE_ADDR);
Packit e9ba0d
	ck_assert_int_eq(nchassis->c_id_len, 5);
Packit e9ba0d
	cid[0] = 1;
Packit e9ba0d
	ip = inet_addr("172.16.101.168");
Packit e9ba0d
	memcpy(cid + 1, &ip, sizeof(in_addr_t));
Packit e9ba0d
	fail_unless(memcmp(nchassis->c_id, cid, 5) == 0);
Packit e9ba0d
	ck_assert_str_eq(nchassis->c_name, "172.16.101.168");
Packit e9ba0d
	ck_assert_str_eq(nchassis->c_descr, "Nortel Ethernet Routing 8610 L3 Switch");
Packit e9ba0d
	ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_addr.inet.s_addr,
Packit e9ba0d
	    (u_int32_t)inet_addr("172.16.101.168"));
Packit e9ba0d
	ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_iface, 0);
Packit e9ba0d
	ck_assert_str_eq(nport->p_descr, "port 2/8");
Packit e9ba0d
	ck_assert_int_eq(nport->p_id_subtype,
Packit e9ba0d
	    LLDP_PORTID_SUBTYPE_LOCAL);
Packit e9ba0d
	ck_assert_int_eq(nport->p_id_len, strlen("00-02-08"));
Packit e9ba0d
	fail_unless(memcmp(nport->p_id,
Packit e9ba0d
		"00-02-08", strlen("00-02-08")) == 0);
Packit e9ba0d
	ck_assert_int_eq(nchassis->c_cap_enabled, 0);
Packit e9ba0d
}
Packit e9ba0d
END_TEST
Packit e9ba0d
Packit e9ba0d
#endif
Packit e9ba0d
Packit e9ba0d
Suite *
Packit e9ba0d
sonmp_suite(void)
Packit e9ba0d
{
Packit e9ba0d
	Suite *s = suite_create("SONMP");
Packit e9ba0d
Packit e9ba0d
#ifdef ENABLE_SONMP
Packit e9ba0d
	TCase *tc_send = tcase_create("Send SONMP packets");
Packit e9ba0d
	TCase *tc_receive = tcase_create("Receive SONMP packets");
Packit e9ba0d
Packit e9ba0d
	tcase_add_checked_fixture(tc_send, pcap_setup, pcap_teardown);
Packit e9ba0d
	tcase_add_test(tc_send, test_send_sonmp);
Packit e9ba0d
	suite_add_tcase(s, tc_send);
Packit e9ba0d
Packit e9ba0d
	tcase_add_test(tc_receive, test_recv_sonmp);
Packit e9ba0d
	suite_add_tcase(s, tc_receive);
Packit e9ba0d
#endif
Packit e9ba0d
Packit e9ba0d
	return s;
Packit e9ba0d
}
Packit e9ba0d
Packit e9ba0d
int
Packit e9ba0d
main()
Packit e9ba0d
{
Packit e9ba0d
	int number_failed;
Packit e9ba0d
	Suite *s = sonmp_suite ();
Packit e9ba0d
	SRunner *sr = srunner_create (s);
Packit e9ba0d
	srunner_set_fork_status (sr, CK_NOFORK); /* Can't fork because
Packit e9ba0d
						    we need to write
Packit e9ba0d
						    files */
Packit e9ba0d
	srunner_run_all (sr, CK_ENV);
Packit e9ba0d
	number_failed = srunner_ntests_failed (sr);
Packit e9ba0d
	srunner_free (sr);
Packit e9ba0d
	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
Packit e9ba0d
}