1 /* -*- mode: c; c-file-style: "openbsd" -*- */
2 /*
3  * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <stdlib.h>
19 #include <sys/socket.h>
20 #include <arpa/inet.h>
21 #include <netinet/in.h>
22 #include <check.h>
23 #include "common.h"
24 
25 char filenameprefix[] = "lldp_send";
26 
27 static struct lldpd test_lldpd = {
28 	.g_config = {
29 		.c_cap_advertise     = 1,  /* Chassis capabilities advertisement */
30 		.c_mgmt_advertise    = 1,  /* Management addresses advertisement */
31 	}
32 };
33 
34 #define ck_assert_str_eq_n(X, Y, N) \
35 	ck_assert_msg(!strncmp(X, Y, N), "Assertion '"#X"=="#Y"' failed: "#X"==\"%s\", "#Y"==\"%s\"", X, Y)
36 
37 static void
check_received_port(struct lldpd_port * sport,struct lldpd_port * rport)38 check_received_port(
39 	struct lldpd_port *sport,
40 	struct lldpd_port *rport)
41 {
42 	ck_assert_int_eq(rport->p_id_subtype, sport->p_id_subtype);
43 	ck_assert_int_eq(rport->p_id_len, sport->p_id_len);
44 	ck_assert_str_eq_n(rport->p_id, sport->p_id, sport->p_id_len);
45 	ck_assert_str_eq(rport->p_descr, sport->p_descr);
46 #ifdef ENABLE_DOT3
47 	ck_assert_int_eq(rport->p_mfs, sport->p_mfs);
48 #endif
49 }
50 
51 static void
check_received_chassis(struct lldpd_chassis * schassis,struct lldpd_chassis * rchassis)52 check_received_chassis(
53 	struct lldpd_chassis *schassis,
54 	struct lldpd_chassis *rchassis)
55 {
56 	ck_assert_int_eq(rchassis->c_id_subtype, schassis->c_id_subtype);
57 	ck_assert_int_eq(rchassis->c_id_len, schassis->c_id_len);
58 	ck_assert_str_eq_n(rchassis->c_id, schassis->c_id, schassis->c_id_len);
59 	ck_assert_str_eq(rchassis->c_name, schassis->c_name);
60 	ck_assert_str_eq(rchassis->c_descr, schassis->c_descr);
61 	ck_assert_int_eq(rchassis->c_cap_available, schassis->c_cap_available);
62 	ck_assert_int_eq(rchassis->c_cap_enabled, schassis->c_cap_enabled);
63 }
64 
65 #ifdef ENABLE_LLDPMED
66 static void
check_received_port_med(struct lldpd_port * sport,struct lldpd_port * rport)67 check_received_port_med(
68 	struct lldpd_port *sport,
69 	struct lldpd_port *rport)
70 {
71 	ck_assert_int_eq(rport->p_med_cap_enabled, sport->p_med_cap_enabled);
72 	ck_assert_int_eq(rport->p_med_cap_enabled, sport->p_med_cap_enabled);
73 	ck_assert_int_eq(
74 		rport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].format,
75 		sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].format);
76 	ck_assert_int_eq(
77 		rport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data_len,
78 		sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data_len);
79 	ck_assert_str_eq_n(
80 		rport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data,
81 		sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data,
82 		sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data_len);
83 	ck_assert_int_eq(
84 		rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].type,
85 		sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].type);
86 	ck_assert_int_eq(
87 		rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].tagged,
88 		sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].tagged);
89 	ck_assert_int_eq(
90 		rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].vid,
91 		sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].vid);
92 	ck_assert_int_eq(
93 		rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].priority,
94 		sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].priority);
95 	ck_assert_int_eq(
96 		rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].dscp,
97 		sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].dscp);
98 	ck_assert_int_eq(
99 		rport->p_med_power.devicetype, sport->p_med_power.devicetype);
100 	ck_assert_int_eq(rport->p_med_power.source, sport->p_med_power.source);
101 	ck_assert_int_eq(rport->p_med_power.priority,
102 		sport->p_med_power.priority);
103 	ck_assert_int_eq(rport->p_med_power.val, sport->p_med_power.val);
104 }
105 
106 static void
check_received_chassis_med(struct lldpd_chassis * schassis,struct lldpd_chassis * rchassis)107 check_received_chassis_med(
108 	struct lldpd_chassis *schassis,
109 	struct lldpd_chassis *rchassis)
110 {
111 	ck_assert_int_eq(rchassis->c_med_cap_available,
112 		schassis->c_med_cap_available);
113 	ck_assert_int_eq(rchassis->c_med_type, schassis->c_med_type);
114 	ck_assert_str_eq(rchassis->c_med_hw, schassis->c_med_hw);
115 	ck_assert_str_eq(rchassis->c_med_fw, schassis->c_med_fw);
116 	ck_assert_str_eq(rchassis->c_med_sw, schassis->c_med_sw);
117 	ck_assert_str_eq(rchassis->c_med_sn, schassis->c_med_sn);
118 }
119 #endif
120 
121 #ifdef ENABLE_DOT3
122 static void
check_received_port_dot3(struct lldpd_port * sport,struct lldpd_port * rport)123 check_received_port_dot3(
124 	struct lldpd_port *sport,
125 	struct lldpd_port *rport)
126 {
127 	ck_assert_int_eq(rport->p_aggregid, sport->p_aggregid);
128 	ck_assert_int_eq(rport->p_macphy.autoneg_support,
129 		sport->p_macphy.autoneg_support);
130 	ck_assert_int_eq(rport->p_macphy.autoneg_enabled,
131 		sport->p_macphy.autoneg_enabled);
132 	ck_assert_int_eq(rport->p_macphy.autoneg_advertised,
133 		sport->p_macphy.autoneg_advertised);
134 	ck_assert_int_eq(rport->p_macphy.mau_type, sport->p_macphy.mau_type);
135 }
136 #endif
137 
START_TEST(test_send_rcv_basic)138 START_TEST (test_send_rcv_basic)
139 {
140 	int n;
141 	struct packet *pkt;
142 	struct lldpd_chassis *nchassis = NULL;
143 	struct lldpd_port *nport = NULL;
144 
145 	/* Populate port and chassis */
146 	hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME;
147 	hardware.h_lport.p_id = "FastEthernet 1/5";
148 	hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id);
149 	hardware.h_lport.p_descr = "Fake port description";
150 	hardware.h_lport.p_mfs = 1516;
151 	chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
152 	chassis.c_id = macaddress;
153 	chassis.c_id_len = ETHER_ADDR_LEN;
154 	chassis.c_name = "First chassis";
155 	chassis.c_descr = "Chassis description";
156 	chassis.c_cap_available = chassis.c_cap_enabled = LLDP_CAP_ROUTER;
157 
158 	/* Build packet */
159 	n = lldp_send(&test_lldpd, &hardware);
160 	if (n != 0) {
161 		fail("unable to build packet");
162 		return;
163 	}
164 	if (TAILQ_EMPTY(&pkts)) {
165 		fail("no packets sent");
166 		return;
167 	}
168 	pkt = TAILQ_FIRST(&pkts);
169 	fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
170 
171 	/* decode the retrieved packet calling lldp_decode() */
172 	fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware,
173 		&nchassis, &nport) != -1);
174 	if (!nchassis || !nport) {
175 		fail("unable to decode packet");
176 		return;
177 	}
178 	/* verify port values */
179 	check_received_port(&hardware.h_lport, nport);
180 	/* verify chassis values */
181 	check_received_chassis(&chassis, nchassis);
182 }
183 END_TEST
184 
185 #define ETHERTYPE_OFFSET 2 * ETHER_ADDR_LEN
186 #define VLAN_TAG_SIZE 2
START_TEST(test_send_rcv_vlan_tx)187 START_TEST (test_send_rcv_vlan_tx)
188 {
189 	int n;
190 	struct packet *pkt;
191 	struct lldpd_chassis *nchassis = NULL;
192 	struct lldpd_port *nport = NULL;
193 	int vlan_id = 100;
194 	int vlan_prio = 5;
195 	int vlan_dei = 1;
196 	unsigned int vlan_tag = 0;
197 	unsigned int tmp;
198 
199 	/* Populate port and chassis */
200 	hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME;
201 	hardware.h_lport.p_id = "FastEthernet 1/5";
202 	hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id);
203 	hardware.h_lport.p_descr = "Fake port description";
204 	hardware.h_lport.p_mfs = 1516;
205 
206 	/* Assembly VLAN tag: Priority(3bits) | DEI(1bit) | VID(12bits) */
207 	vlan_tag = ((vlan_prio & 0x7) << 13) |
208 		   ((vlan_dei & 0x1) << 12) |
209 		   (vlan_id & 0xfff);
210 	hardware.h_lport.p_vlan_tx_tag = vlan_tag;
211 	hardware.h_lport.p_vlan_tx_enabled = 1;
212 	chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
213 	chassis.c_id = macaddress;
214 	chassis.c_id_len = ETHER_ADDR_LEN;
215 	chassis.c_name = "First chassis";
216 	chassis.c_descr = "Chassis description";
217 	chassis.c_cap_available = chassis.c_cap_enabled = LLDP_CAP_ROUTER;
218 
219 	/* Build packet */
220 	n = lldp_send(&test_lldpd, &hardware);
221 	if (n != 0) {
222 		fail("unable to build packet");
223 		return;
224 	}
225 	if (TAILQ_EMPTY(&pkts)) {
226 		fail("no packets sent");
227 		return;
228 	}
229 	pkt = TAILQ_FIRST(&pkts);
230 	fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
231 
232 	/* Check ETHER_TYPE, should be VLAN */
233 	memcpy(&tmp, (unsigned char*) pkt->data + ETHERTYPE_OFFSET, ETHER_TYPE_LEN);
234 	ck_assert_uint_eq(ntohl(tmp)>>16, ETHERTYPE_VLAN);
235 
236 	/* Check VLAN tag */
237 	memcpy(&tmp, (unsigned char*) pkt->data + ETHERTYPE_OFFSET + ETHER_TYPE_LEN, VLAN_TAG_SIZE);
238 	ck_assert_uint_eq(ntohl(tmp)>>16, vlan_tag);
239 
240 	/* Remove VLAN ethertype and VLAN tag */
241 	memmove((unsigned char*) pkt->data + ETHERTYPE_OFFSET,
242 		/* move all after VLAN tag */
243 		(unsigned char*) pkt->data + ETHERTYPE_OFFSET + ETHER_TYPE_LEN + VLAN_TAG_SIZE,
244 		/* size without src and dst MAC, VLAN tag */
245 		pkt->size - (ETHERTYPE_OFFSET + ETHER_TYPE_LEN + VLAN_TAG_SIZE));
246 
247 	/* Decode the packet without VLAN tag, calling lldp_decode() */
248 	fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware,
249 		&nchassis, &nport) != -1);
250 	if (!nchassis || !nport) {
251 		fail("unable to decode packet");
252 		return;
253 	}
254 
255 	/* Verify port values (VLAN information is not checked here) */
256 	check_received_port(&hardware.h_lport, nport);
257 	/* Verify chassis values */
258 	check_received_chassis(&chassis, nchassis);
259 }
260 END_TEST
261 
262 #ifdef ENABLE_DOT1
263 /* This test case tests send and receive of all DOT1 TLVs(2005 and 2009):
264    Port Valn ID, VLAN, Port Protocol VLAN ID, Protocol Identity,
265    VID Usage Digest, Management VID, and 802.1ax Link Aggregation TLVs */
START_TEST(test_send_rcv_dot1_tlvs)266 START_TEST (test_send_rcv_dot1_tlvs)
267 {
268 	int n;
269 	struct lldpd_vlan *rvlan, vlan1, vlan2, vlan3;
270 	struct lldpd_ppvid ppvid, *rppvid;
271 	struct lldpd_pi pi1, pi2, *rpi;
272 	struct lldpd_chassis *nchassis = NULL;
273 	struct lldpd_port *nport = NULL;
274 	struct packet *pkt;
275 
276 	/* Populate port and chassis */
277 	hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR;
278 	hardware.h_lport.p_id = macaddress;
279 	hardware.h_lport.p_id_len = ETHER_ADDR_LEN;
280 	hardware.h_lport.p_descr = "Fake port description";
281 	hardware.h_lport.p_mfs = 1516;
282 	hardware.h_lport.p_pvid = 1500;
283 	chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL;
284 	chassis.c_id = "Chassis name";
285 	chassis.c_id_len = strlen(chassis.c_id);
286 	chassis.c_name = "Second chassis";
287 	chassis.c_descr = "Chassis description";
288 	chassis.c_cap_available = LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE;
289 	chassis.c_cap_enabled = LLDP_CAP_ROUTER;
290 	vlan1.v_name = "Voice"; vlan1.v_vid = 157;
291 	vlan2.v_name = "Data"; vlan2.v_vid = 1247;
292 	vlan3.v_name = "Control"; vlan3.v_vid = 741;
293 	TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan1, v_entries);
294 	TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan2, v_entries);
295 	TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan3, v_entries);
296 	ppvid.p_cap_status = 3;
297 	ppvid.p_ppvid = 1500;
298 	TAILQ_INSERT_TAIL(&hardware.h_lport.p_ppvids, &ppvid, p_entries);
299 	pi1.p_pi = "IEEE Link Aggregration Control Protocol 802.3ad";
300 	pi1.p_pi_len = strlen(pi1.p_pi);
301 	pi2.p_pi = "IEEE Link Layer Discovery Protocol 802.1ab-2005";
302 	pi2.p_pi_len = strlen(pi2.p_pi);
303 	TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi1, p_entries);
304 	TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi2, p_entries);
305 
306 	/* Build packet */
307 	n = lldp_send(&test_lldpd, &hardware);
308 	if (n != 0) {
309 		fail("unable to build packet");
310 		return;
311 	}
312 	if (TAILQ_EMPTY(&pkts)) {
313 		fail("no packets sent");
314 		return;
315 	}
316 	pkt = TAILQ_FIRST(&pkts);
317 	fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
318 
319 	/* decode the retrieved packet calling lldp_decode() */
320 	fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware,
321 		&nchassis, &nport) != -1);
322 	if (!nchassis || !nport) {
323 		fail("unable to decode packet");
324 		return;
325 	}
326 
327 	/* verify port values */
328 	check_received_port(&hardware.h_lport, nport);
329 	/* verify chassis values */
330 	check_received_chassis(&chassis, nchassis);
331 
332 	if (TAILQ_EMPTY(&nport->p_vlans)) {
333 		fail("no VLAN");
334 		return;
335 	}
336 
337 	rvlan = TAILQ_FIRST(&nport->p_vlans);
338 	ck_assert_int_eq(rvlan->v_vid, vlan1.v_vid);
339 	ck_assert_str_eq(rvlan->v_name, vlan1.v_name);
340 
341 	rvlan = TAILQ_NEXT(rvlan, v_entries);
342 	if (!rvlan) {
343 		fail("no more VLAN");
344 		return;
345 	}
346 	ck_assert_int_eq(rvlan->v_vid, vlan2.v_vid);
347 	ck_assert_str_eq(rvlan->v_name, vlan2.v_name);
348 
349 	rvlan = TAILQ_NEXT(rvlan, v_entries);
350 	if (!rvlan) {
351 		fail("no more VLAN");
352 		return;
353 	}
354 	ck_assert_int_eq(rvlan->v_vid, vlan3.v_vid);
355 	ck_assert_str_eq(rvlan->v_name, vlan3.v_name);
356 
357 	rvlan = TAILQ_NEXT(rvlan, v_entries);
358 	fail_unless(rvlan == NULL);
359 
360 	ck_assert_int_eq(nport->p_pvid, hardware.h_lport.p_pvid);
361 
362 	if (TAILQ_EMPTY(&nport->p_ppvids)) {
363 		fail("no Port Protocal VLAN ID");
364 		return;
365 	}
366 	rppvid = TAILQ_FIRST(&nport->p_ppvids);
367 	ck_assert_int_eq(rppvid->p_cap_status, ppvid.p_cap_status);
368 	ck_assert_int_eq(rppvid->p_ppvid, ppvid.p_ppvid);
369 
370 	if (TAILQ_EMPTY(&nport->p_pids)) {
371 		fail("no Protocal Identity TLV");
372 		return;
373 	}
374 	rpi = TAILQ_FIRST(&nport->p_pids);
375 	ck_assert_int_eq(rpi->p_pi_len, pi1.p_pi_len);
376 	ck_assert_str_eq_n(rpi->p_pi, pi1.p_pi, pi1.p_pi_len);
377 
378 	rpi = TAILQ_NEXT(rpi, p_entries);
379 	if (!rpi) {
380 		fail("no more Protocol Identity TLVs");
381 		return;
382 	}
383 	ck_assert_int_eq(rpi->p_pi_len, pi2.p_pi_len);
384 	ck_assert_str_eq_n(rpi->p_pi, pi2.p_pi, pi2.p_pi_len);
385 
386 	rpi = TAILQ_NEXT(rpi, p_entries);
387 	fail_unless(rpi == NULL);
388 }
389 END_TEST
390 #endif
391 
392 #ifdef ENABLE_LLDPMED
START_TEST(test_send_rcv_med)393 START_TEST (test_send_rcv_med)
394 {
395 	int n;
396 	struct packet *pkt;
397 	struct lldpd_chassis *nchassis = NULL;
398 	struct lldpd_port *nport = NULL;
399 
400 	/* Populate port and chassis */
401 	hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR;
402 	hardware.h_lport.p_id = macaddress;
403 	hardware.h_lport.p_id_len = ETHER_ADDR_LEN;
404 	hardware.h_lport.p_descr = "Fake port description";
405 	hardware.h_lport.p_mfs = 1516;
406 	chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL;
407 	chassis.c_id = "Chassis name";
408 	chassis.c_id_len = strlen(chassis.c_id);
409 	chassis.c_name = "Third chassis";
410 	chassis.c_descr = "Chassis description";
411 	chassis.c_cap_available = LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE;
412 	chassis.c_cap_enabled = LLDP_CAP_ROUTER;
413 	chassis.c_med_cap_available = LLDP_MED_CAP_CAP | LLDP_MED_CAP_POLICY |
414 		LLDP_MED_CAP_LOCATION | LLDP_MED_CAP_MDI_PSE |
415 		LLDP_MED_CAP_IV;
416 	chassis.c_med_type = LLDP_MED_CLASS_III;
417 	chassis.c_med_hw = "hardware rev 5";
418 	chassis.c_med_fw = "47b5";
419 	chassis.c_med_sw = "2.6.22b5";
420 	chassis.c_med_sn = "SN 47842";
421 	hardware.h_lport.p_med_cap_enabled = chassis.c_med_cap_available;
422 	hardware.h_lport.p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].format =
423 		LLDP_MED_LOCFORMAT_CIVIC;
424 	hardware.h_lport.p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data = "Your favorite city";
425 	hardware.h_lport.p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data_len =
426 		sizeof("Your favorite city");
427 	hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].type =
428 		LLDP_MED_APPTYPE_SOFTPHONEVOICE;
429 	hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].tagged =
430 		1;
431 	hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].vid =
432 		51;
433 	hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].priority =
434 		6;
435 	hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].dscp =
436 		46;
437 	hardware.h_lport.p_med_power.devicetype = LLDP_MED_POW_TYPE_PSE;
438 	hardware.h_lport.p_med_power.source = LLDP_MED_POW_SOURCE_PRIMARY;
439 	hardware.h_lport.p_med_power.priority = LLDP_MED_POW_PRIO_HIGH;
440 	hardware.h_lport.p_med_power.val = 65;
441 
442 	/* Build packet */
443 	n = lldp_send(&test_lldpd, &hardware);
444 	if (n != 0) {
445 		fail("unable to build packet");
446 		return;
447 	}
448 	if (TAILQ_EMPTY(&pkts)) {
449 		fail("no packets sent");
450 		return;
451 	}
452 	pkt = TAILQ_FIRST(&pkts);
453 	fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
454 
455 	/* decode the retrieved packet calling lldp_decode() */
456 	fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware,
457 		&nchassis, &nport) != -1);
458 	if (!nchassis || !nport) {
459 		fail("unable to decode packet");
460 		return;
461 	}
462 	/* verify port values */
463 	check_received_port(&hardware.h_lport, nport);
464 	/* verify chassis values */
465 	check_received_chassis(&chassis, nchassis);
466 
467 	/* veridfy med content */
468 	check_received_port_med(&hardware.h_lport, nport);
469 	check_received_chassis_med(&chassis, nchassis);
470 }
471 END_TEST
472 #endif
473 
474 #ifdef ENABLE_DOT3
START_TEST(test_send_rcv_dot3)475 START_TEST (test_send_rcv_dot3)
476 {
477 	int n;
478 	struct lldpd_chassis *nchassis = NULL;
479 	struct lldpd_port *nport = NULL;
480 	struct packet *pkt;
481 
482 	/* Populate port and chassis */
483 	hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME;
484 	hardware.h_lport.p_id = "FastEthernet 1/5";
485 	hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id);
486 	hardware.h_lport.p_descr = "Fake port description";
487 	hardware.h_lport.p_mfs = 1516;
488 	hardware.h_lport.p_aggregid = 5;
489 	hardware.h_lport.p_macphy.autoneg_support = 1;
490 	hardware.h_lport.p_macphy.autoneg_enabled = 1;
491 	hardware.h_lport.p_macphy.autoneg_advertised = LLDP_DOT3_LINK_AUTONEG_10BASE_T |
492 		LLDP_DOT3_LINK_AUTONEG_10BASET_FD | LLDP_DOT3_LINK_AUTONEG_100BASE_TX |
493 		LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD;
494 	hardware.h_lport.p_macphy.mau_type = LLDP_DOT3_MAU_100BASETXFD;
495 	chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
496 	chassis.c_id = macaddress;
497 	chassis.c_id_len = ETHER_ADDR_LEN;
498 	chassis.c_name = "Fourth chassis";
499 	chassis.c_descr = "Long chassis description";
500 	chassis.c_cap_available = chassis.c_cap_enabled = LLDP_CAP_ROUTER | LLDP_CAP_WLAN;
501 
502 	/* Build packet */
503 	n = lldp_send(&test_lldpd, &hardware);
504 	if (n != 0) {
505 		fail("unable to build packet");
506 		return;
507 	}
508 	if (TAILQ_EMPTY(&pkts)) {
509 		fail("no packets sent");
510 		return;
511 	}
512 	pkt = TAILQ_FIRST(&pkts);
513 	fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
514 
515 	/* decode the retrieved packet calling lldp_decode() */
516 	fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware,
517 		&nchassis, &nport) != -1);
518 	if (!nchassis || !nport) {
519 		fail("unable to decode packet");
520 		return;
521 	}
522 	/* verify port values */
523 	check_received_port(&hardware.h_lport, nport);
524 	/* verify chassis values */
525 	check_received_chassis(&chassis, nchassis);
526 	/* verify dot3 values */
527 	check_received_port_dot3(&hardware.h_lport, nport);
528 }
529 END_TEST
530 #endif
531 
START_TEST(test_recv_min)532 START_TEST (test_recv_min)
533 {
534 	char pkt1[] = {
535 		0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x17,
536 		0xd1, 0xa8, 0x35, 0xbe, 0x88, 0xcc, 0x02, 0x07,
537 		0x04, 0x00, 0x17, 0xd1, 0xa8, 0x35, 0xbf, 0x04,
538 		0x07, 0x03, 0x00, 0x17, 0xd1, 0xa8, 0x36, 0x02,
539 		0x06, 0x02, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
540 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 		0x00, 0x00, 0x00, 0x00 };
543 	/* This is:
544 Ethernet II, Src: Nortel_a8:35:be (00:17:d1:a8:35:be), Dst: LLDP_Multicast (01:80:c2:00:00:0e)
545     Destination: LLDP_Multicast (01:80:c2:00:00:0e)
546     Source: Nortel_a8:35:be (00:17:d1:a8:35:be)
547     Type: 802.1 Link Layer Discovery Protocol (LLDP) (0x88cc)
548 Link Layer Discovery Protocol
549     Chassis Subtype = MAC address
550         0000 001. .... .... = TLV Type: Chassis Id (1)
551         .... ...0 0000 0111 = TLV Length: 7
552         Chassis Id Subtype: MAC address (4)
553         Chassis Id: Nortel_a8:35:bf (00:17:d1:a8:35:bf)
554     Port Subtype = MAC address
555         0000 010. .... .... = TLV Type: Port Id (2)
556         .... ...0 0000 0111 = TLV Length: 7
557         Port Id Subtype: MAC address (3)
558         Port Id: Nortel_a8:36:02 (00:17:d1:a8:36:02)
559     Time To Live = 120 sec
560         0000 011. .... .... = TLV Type: Time to Live (3)
561         .... ...0 0000 0010 = TLV Length: 2
562         Seconds: 120
563     End of LLDPDU
564         0000 000. .... .... = TLV Type: End of LLDPDU (0)
565         .... ...0 0000 0000 = TLV Length: 0
566 	*/
567 	struct lldpd_chassis *nchassis = NULL;
568 	struct lldpd_port *nport = NULL;
569 	char mac1[] = { 0x0, 0x17, 0xd1, 0xa8, 0x35, 0xbf };
570 	char mac2[] = { 0x0, 0x17, 0xd1, 0xa8, 0x36, 0x02 };
571 
572 	fail_unless(lldp_decode(NULL, pkt1, sizeof(pkt1), &hardware,
573 		&nchassis, &nport) != -1);
574 	if (!nchassis || !nport) {
575 		fail("unable to decode packet");
576 		return;
577 	}
578 	ck_assert_int_eq(nchassis->c_id_subtype,
579 	    LLDP_CHASSISID_SUBTYPE_LLADDR);
580 	ck_assert_int_eq(nchassis->c_id_len, ETHER_ADDR_LEN);
581 	fail_unless(memcmp(mac1, nchassis->c_id, ETHER_ADDR_LEN) == 0);
582 	ck_assert_int_eq(nport->p_id_subtype,
583 	    LLDP_PORTID_SUBTYPE_LLADDR);
584 	ck_assert_int_eq(nport->p_id_len, ETHER_ADDR_LEN);
585 	fail_unless(memcmp(mac2, nport->p_id, ETHER_ADDR_LEN) == 0);
586 	ck_assert_ptr_eq(nchassis->c_name, NULL);
587 	ck_assert_ptr_eq(nchassis->c_descr, NULL);
588 	ck_assert_ptr_eq(nport->p_descr, NULL);
589 	ck_assert_int_eq(nport->p_ttl, 120);
590 }
591 END_TEST
592 
START_TEST(test_recv_lldpd)593 START_TEST (test_recv_lldpd)
594 {
595 	/* This is a frame generated by lldpd */
596 	char pkt1[] = {
597 		0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x16,
598 		0x17, 0x2f, 0xa1, 0xb6, 0x88, 0xcc, 0x02, 0x07,
599 		0x04, 0x00, 0x16, 0x17, 0x2f, 0xa1, 0xb6, 0x04,
600 		0x07, 0x03, 0x00, 0x16, 0x17, 0x2f, 0xa1, 0xb6,
601 		0x06, 0x02, 0x00, 0x78, 0x0a, 0x1a, 0x6e, 0x61,
602 		0x72, 0x75, 0x74, 0x6f, 0x2e, 0x58, 0x58, 0x58,
603 		0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
604 		0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
605 		0x0c, 0x3f, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20,
606 		0x32, 0x2e, 0x36, 0x2e, 0x32, 0x39, 0x2d, 0x32,
607 		0x2d, 0x61, 0x6d, 0x64, 0x36, 0x34, 0x20, 0x23,
608 		0x31, 0x20, 0x53, 0x4d, 0x50, 0x20, 0x53, 0x75,
609 		0x6e, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x31, 0x37,
610 		0x20, 0x31, 0x37, 0x3a, 0x31, 0x35, 0x3a, 0x34,
611 		0x37, 0x20, 0x55, 0x54, 0x43, 0x20, 0x32, 0x30,
612 		0x30, 0x39, 0x20, 0x78, 0x38, 0x36, 0x5f, 0x36,
613 		0x34, 0x0e, 0x04, 0x00, 0x1c, 0x00, 0x14, 0x10,
614 		0x0c, 0x05, 0x01, 0x0a, 0xee, 0x50, 0x4b, 0x02,
615 		0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x04, 0x65,
616 		0x74, 0x68, 0x30, 0xfe, 0x09, 0x00, 0x12, 0x0f,
617 		0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x09,
618 		0x00, 0x12, 0x0f, 0x01, 0x03, 0x6c, 0x03, 0x00,
619 		0x10, 0xfe, 0x06, 0x00, 0x12, 0x0f, 0x04, 0x05,
620 		0xdc, 0xfe, 0x07, 0x00, 0x12, 0xbb, 0x01, 0x00,
621 		0x00, 0x00, 0xfe, 0x0f, 0x00, 0x12, 0xbb, 0x05,
622 		0x4e, 0x44, 0x39, 0x39, 0x31, 0x37, 0x38, 0x39,
623 		0x37, 0x30, 0x32, 0xfe, 0x0b, 0x00, 0x12, 0xbb,
624 		0x06, 0x30, 0x38, 0x30, 0x30, 0x31, 0x32, 0x20,
625 		0xfe, 0x12, 0x00, 0x12, 0xbb, 0x07, 0x32, 0x2e,
626 		0x36, 0x2e, 0x32, 0x39, 0x2d, 0x32, 0x2d, 0x61,
627 		0x6d, 0x64, 0x36, 0x34, 0xfe, 0x10, 0x00, 0x12,
628 		0xbb, 0x08, 0x31, 0x30, 0x35, 0x38, 0x32, 0x30,
629 		0x38, 0x35, 0x30, 0x30, 0x30, 0x39, 0xfe, 0x15,
630 		0x00, 0x12, 0xbb, 0x09, 0x4e, 0x45, 0x43, 0x20,
631 		0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72,
632 		0x73, 0x20, 0x53, 0x41, 0x53, 0xfe, 0x13, 0x00,
633 		0x12, 0xbb, 0x0a, 0x50, 0x4f, 0x57, 0x45, 0x52,
634 		0x4d, 0x41, 0x54, 0x45, 0x20, 0x56, 0x4c, 0x33,
635 		0x35, 0x30, 0xfe, 0x0d, 0x00, 0x12, 0xbb, 0x0b,
636 		0x31, 0x30, 0x30, 0x32, 0x30, 0x37, 0x31, 0x32,
637 		0x30, 0x00, 0x00 };
638 	/* This is:
639 Ethernet II, Src: Msi_2f:a1:b6 (00:16:17:2f:a1:b6), Dst: LLDP_Multicast (01:80:c2:00:00:0e)
640     Destination: LLDP_Multicast (01:80:c2:00:00:0e)
641     Source: Msi_2f:a1:b6 (00:16:17:2f:a1:b6)
642     Type: 802.1 Link Layer Discovery Protocol (LLDP) (0x88cc)
643 Link Layer Discovery Protocol
644     Chassis Subtype = MAC address
645         0000 001. .... .... = TLV Type: Chassis Id (1)
646         .... ...0 0000 0111 = TLV Length: 7
647         Chassis Id Subtype: MAC address (4)
648         Chassis Id: Msi_2f:a1:b6 (00:16:17:2f:a1:b6)
649     Port Subtype = MAC address
650         0000 010. .... .... = TLV Type: Port Id (2)
651         .... ...0 0000 0111 = TLV Length: 7
652         Port Id Subtype: MAC address (3)
653         Port Id: Msi_2f:a1:b6 (00:16:17:2f:a1:b6)
654     Time To Live = 120 sec
655         0000 011. .... .... = TLV Type: Time to Live (3)
656         .... ...0 0000 0010 = TLV Length: 2
657         Seconds: 120
658     System Name = naruto.XXXXXXXXXXXXXXXXXXX
659         0000 101. .... .... = TLV Type: System Name (5)
660         .... ...0 0001 1010 = TLV Length: 26
661         System Name = naruto.bureau.b1.p.fti.net
662     System Description = Linux 2.6.29-2-amd64 #1 SMP Sun May 17 17:15:47 UTC 2009 x86_64
663         0000 110. .... .... = TLV Type: System Description (6)
664         .... ...0 0011 1111 = TLV Length: 63
665         System Description = Linux 2.6.29-2-amd64 #1 SMP Sun May 17 17:15:47 UTC 2009 x86_64
666     Capabilities
667         0000 111. .... .... = TLV Type: System Capabilities (7)
668         .... ...0 0000 0100 = TLV Length: 4
669         Capabilities: 0x001c
670             .... .... .... .1.. = Bridge
671             .... .... .... 1... = WLAN access point
672             .... .... ...1 .... = Router
673         Enabled Capabilities: 0x0014
674             .... .... .... .1.. = Bridge
675             .... .... ...1 .... = Router
676     Management Address
677         0001 000. .... .... = TLV Type: Management Address (8)
678         .... ...0 0000 1100 = TLV Length: 12
679         Address String Length: 5
680         Address Subtype: IPv4 (1)
681         Management Address: 10.238.80.75
682         Interface Subtype: ifIndex (2)
683         Interface Number: 3
684         OID String Length: 0
685     Port Description = eth0
686         0000 100. .... .... = TLV Type: Port Description (4)
687         .... ...0 0000 0100 = TLV Length: 4
688         Port Description: eth0
689     IEEE 802.3 - Link Aggregation
690         1111 111. .... .... = TLV Type: Organization Specific (127)
691         .... ...0 0000 1001 = TLV Length: 9
692         Organization Unique Code: IEEE 802.3 (0x00120f)
693         IEEE 802.3 Subtype: Link Aggregation (0x03)
694         Aggregation Status: 0x01
695             .... ...1 = Aggregation Capability: Yes
696             .... ..0. = Aggregation Status: Not Enabled
697         Aggregated Port Id: 0
698     IEEE 802.3 - MAC/PHY Configuration/Status
699         1111 111. .... .... = TLV Type: Organization Specific (127)
700         .... ...0 0000 1001 = TLV Length: 9
701         Organization Unique Code: IEEE 802.3 (0x00120f)
702         IEEE 802.3 Subtype: MAC/PHY Configuration/Status (0x01)
703         Auto-Negotiation Support/Status: 0x03
704             .... ...1 = Auto-Negotiation: Supported
705             .... ..1. = Auto-Negotiation: Enabled
706         PMD Auto-Negotiation Advertised Capability: 0x6C03
707             .... .... .... ...1 = 1000BASE-T (full duplex mode)
708             .... .... .... ..1. = 1000BASE-T (half duplex mode)
709             .... .1.. .... .... = 100BASE-TX (full duplex mode)
710             .... 1... .... .... = 100BASE-TX (half duplex mode)
711             ..1. .... .... .... = 10BASE-T (full duplex mode)
712             .1.. .... .... .... = 10BASE-T (half duplex mode)
713         Operational MAU Type: 100BaseTXFD - 2 pair category 5 UTP, full duplex mode (0x0010)
714     IEEE 802.3 - Maximum Frame Size
715         1111 111. .... .... = TLV Type: Organization Specific (127)
716         .... ...0 0000 0110 = TLV Length: 6
717         Organization Unique Code: IEEE 802.3 (0x00120f)
718         IEEE 802.3 Subtype: Maximum Frame Size (0x04)
719         Maximum Frame Size: 1500
720     TIA - Media Capabilities
721         1111 111. .... .... = TLV Type: Organization Specific (127)
722         .... ...0 0000 0111 = TLV Length: 7
723         Organization Unique Code: TIA (0x0012bb)
724         Media Subtype: Media Capabilities (0x01)
725         Capabilities: 0x0000
726         Class Type: Type Not Defined
727     TIA - Inventory - Hardware Revision
728         1111 111. .... .... = TLV Type: Organization Specific (127)
729         .... ...0 0000 1111 = TLV Length: 15
730         Organization Unique Code: TIA (0x0012bb)
731         Media Subtype: Inventory - Hardware Revision (0x05)
732         Hardware Revision: ND991789702
733     TIA - Inventory - Firmware Revision
734         1111 111. .... .... = TLV Type: Organization Specific (127)
735         .... ...0 0000 1011 = TLV Length: 10
736         Organization Unique Code: TIA (0x0012bb)
737         Media Subtype: Inventory - Firmware Revision (0x06)
738         Firmware Revision: 080012
739     TIA - Inventory - Software Revision
740         1111 111. .... .... = TLV Type: Organization Specific (127)
741         .... ...0 0001 0010 = TLV Length: 18
742         Organization Unique Code: TIA (0x0012bb)
743         Media Subtype: Inventory - Software Revision (0x07)
744         Software Revision: 2.6.29-2-amd64
745     TIA - Inventory - Serial Number
746         1111 111. .... .... = TLV Type: Organization Specific (127)
747         .... ...0 0001 0000 = TLV Length: 16
748         Organization Unique Code: TIA (0x0012bb)
749         Media Subtype: Inventory - Serial Number (0x08)
750         Serial Number: 105820850009
751     TIA - Inventory - Manufacturer Name
752         1111 111. .... .... = TLV Type: Organization Specific (127)
753         .... ...0 0001 0101 = TLV Length: 21
754         Organization Unique Code: TIA (0x0012bb)
755         Media Subtype: Inventory - Manufacturer Name (0x09)
756         Manufacturer Name: NEC Computers SAS
757     TIA - Inventory - Model Name
758         1111 111. .... .... = TLV Type: Organization Specific (127)
759         .... ...0 0001 0011 = TLV Length: 19
760         Organization Unique Code: TIA (0x0012bb)
761         Media Subtype: Inventory - Model Name (0x0a)
762         Model Name: POWERMATE VL350
763     TIA - Inventory - Asset ID
764         1111 111. .... .... = TLV Type: Organization Specific (127)
765         .... ...0 0000 1101 = TLV Length: 13
766         Organization Unique Code: TIA (0x0012bb)
767         Media Subtype: Inventory - Asset ID (0x0b)
768         Asset ID: 100207120
769     End of LLDPDU
770         0000 000. .... .... = TLV Type: End of LLDPDU (0)
771         .... ...0 0000 0000 = TLV Length: 0
772 	*/
773 	struct lldpd_chassis *nchassis = NULL;
774 	struct lldpd_port *nport = NULL;
775 	char mac1[] = { 0x00, 0x16, 0x17, 0x2f, 0xa1, 0xb6 };
776 
777 	fail_unless(lldp_decode(NULL, pkt1, sizeof(pkt1), &hardware,
778 		&nchassis, &nport) != -1);
779 	if (!nchassis || !nport) {
780 		fail("unable to decode packet");
781 		return;
782 	}
783 	ck_assert_int_eq(nchassis->c_id_subtype,
784 	    LLDP_CHASSISID_SUBTYPE_LLADDR);
785 	ck_assert_int_eq(nchassis->c_id_len, ETHER_ADDR_LEN);
786 	fail_unless(memcmp(mac1, nchassis->c_id, ETHER_ADDR_LEN) == 0);
787 	ck_assert_int_eq(nport->p_id_subtype,
788 	    LLDP_PORTID_SUBTYPE_LLADDR);
789 	ck_assert_int_eq(nport->p_id_len, ETHER_ADDR_LEN);
790 	fail_unless(memcmp(mac1, nport->p_id, ETHER_ADDR_LEN) == 0);
791 	ck_assert_int_eq(nport->p_ttl, 120);
792 	ck_assert_str_eq(nchassis->c_name, "naruto.XXXXXXXXXXXXXXXXXXX");
793 	ck_assert_str_eq(nchassis->c_descr,
794 	    "Linux 2.6.29-2-amd64 #1 SMP Sun May 17 17:15:47 UTC 2009 x86_64");
795 	ck_assert_str_eq(nport->p_descr, "eth0");
796 	ck_assert_int_eq(nchassis->c_cap_available,
797 	    LLDP_CAP_WLAN | LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE);
798 	ck_assert_int_eq(nchassis->c_cap_enabled,
799 	    LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE);
800 	ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_addr.inet.s_addr,
801 	    (u_int32_t)inet_addr("10.238.80.75"));
802 	ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_iface, 3);
803 #ifdef ENABLE_DOT3
804 	ck_assert_int_eq(nport->p_aggregid, 0);
805 	ck_assert_int_eq(nport->p_macphy.autoneg_enabled, 1);
806 	ck_assert_int_eq(nport->p_macphy.autoneg_support, 1);
807 	ck_assert_int_eq(nport->p_macphy.autoneg_advertised,
808 	    LLDP_DOT3_LINK_AUTONEG_1000BASE_TFD |
809 	    LLDP_DOT3_LINK_AUTONEG_1000BASE_T |
810 	    LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD |
811 	    LLDP_DOT3_LINK_AUTONEG_100BASE_TX |
812 	    LLDP_DOT3_LINK_AUTONEG_10BASET_FD |
813 	    LLDP_DOT3_LINK_AUTONEG_10BASE_T);
814 	ck_assert_int_eq(nport->p_macphy.mau_type,
815 	    LLDP_DOT3_MAU_100BASETXFD);
816 	ck_assert_int_eq(nport->p_mfs, 1500);
817 #endif
818 #ifdef ENABLE_LLDPMED
819 	ck_assert_int_eq(nchassis->c_med_type, 0);
820 	ck_assert_str_eq(nchassis->c_med_hw, "ND991789702");
821 	ck_assert_str_eq(nchassis->c_med_fw, "080012 "); /* Extra space */
822 	ck_assert_str_eq(nchassis->c_med_sw, "2.6.29-2-amd64");
823 	ck_assert_str_eq(nchassis->c_med_sn, "105820850009");
824 	ck_assert_str_eq(nchassis->c_med_manuf, "NEC Computers SAS");
825 	ck_assert_str_eq(nchassis->c_med_model, "POWERMATE VL350");
826 	ck_assert_str_eq(nchassis->c_med_asset, "100207120");
827 #endif
828 }
829 END_TEST
830 
831 Suite *
lldp_suite(void)832 lldp_suite(void)
833 {
834 	Suite *s = suite_create("LLDP");
835 	TCase *tc_send = tcase_create("Send LLDP packets");
836 	TCase *tc_receive = tcase_create("Receive LLDP packets");
837 
838 	/* Send tests are first run without knowing the result. The
839 	   result is then checked with:
840 	     tshark -V -T text -r tests/lldp_send_0000.pcap
841 
842 	   If the result is correct, then, we get the packet as C
843 	   bytes using wireshark export to C arrays (tshark seems not
844 	   be able to do this).
845 	*/
846 
847 	tcase_add_checked_fixture(tc_send, pcap_setup, pcap_teardown);
848 	tcase_add_test(tc_send, test_send_rcv_basic);
849 	tcase_add_test(tc_send, test_send_rcv_vlan_tx);
850 #ifdef ENABLE_DOT1
851 	tcase_add_test(tc_send, test_send_rcv_dot1_tlvs);
852 #endif
853 #ifdef ENABLE_LLDPMED
854 	tcase_add_test(tc_send, test_send_rcv_med);
855 #endif
856 #ifdef ENABLE_DOT3
857 	tcase_add_test(tc_send, test_send_rcv_dot3);
858 #endif
859 	suite_add_tcase(s, tc_send);
860 
861 	tcase_add_test(tc_receive, test_recv_min);
862 	tcase_add_test(tc_receive, test_recv_lldpd);
863 	suite_add_tcase(s, tc_receive);
864 
865 	return s;
866 }
867 
868 int
main()869 main()
870 {
871 	int number_failed;
872 	Suite *s = lldp_suite ();
873 	SRunner *sr = srunner_create (s);
874 	srunner_set_fork_status (sr, CK_NOFORK); /* Can't fork because
875 						    we need to write
876 						    files */
877 	srunner_run_all (sr, CK_ENV);
878 	number_failed = srunner_ntests_failed (sr);
879 	srunner_free (sr);
880 	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
881 }
882