]> git.ipfire.org Git - thirdparty/lldpd.git/blob - tests/check_lldp.c
tests: display tests/test-suite.log on errors
[thirdparty/lldpd.git] / tests / check_lldp.c
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
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
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
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
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
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
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 #ifdef ENABLE_DOT1
186 /* This test case tests send and receive of all DOT1 TLVs(2005 and 2009):
187 Port Valn ID, VLAN, Port Protocol VLAN ID, Protocol Identity,
188 VID Usage Digest, Management VID, and 802.1ax Link Aggregation TLVs */
189 START_TEST (test_send_rcv_dot1_tlvs)
190 {
191 int n;
192 struct lldpd_vlan *rvlan, vlan1, vlan2, vlan3;
193 struct lldpd_ppvid ppvid, *rppvid;
194 struct lldpd_pi pi1, pi2, *rpi;
195 struct lldpd_chassis *nchassis = NULL;
196 struct lldpd_port *nport = NULL;
197 struct packet *pkt;
198
199 /* Populate port and chassis */
200 hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR;
201 hardware.h_lport.p_id = macaddress;
202 hardware.h_lport.p_id_len = ETHER_ADDR_LEN;
203 hardware.h_lport.p_descr = "Fake port description";
204 hardware.h_lport.p_mfs = 1516;
205 hardware.h_lport.p_pvid = 1500;
206 chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL;
207 chassis.c_id = "Chassis name";
208 chassis.c_id_len = strlen(chassis.c_id);
209 chassis.c_name = "Second chassis";
210 chassis.c_descr = "Chassis description";
211 chassis.c_cap_available = LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE;
212 chassis.c_cap_enabled = LLDP_CAP_ROUTER;
213 vlan1.v_name = "Voice"; vlan1.v_vid = 157;
214 vlan2.v_name = "Data"; vlan2.v_vid = 1247;
215 vlan3.v_name = "Control"; vlan3.v_vid = 741;
216 TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan1, v_entries);
217 TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan2, v_entries);
218 TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan3, v_entries);
219 ppvid.p_cap_status = 3;
220 ppvid.p_ppvid = 1500;
221 TAILQ_INSERT_TAIL(&hardware.h_lport.p_ppvids, &ppvid, p_entries);
222 pi1.p_pi = "IEEE Link Aggregration Control Protocol 802.3ad";
223 pi1.p_pi_len = strlen(pi1.p_pi);
224 pi2.p_pi = "IEEE Link Layer Discovery Protocol 802.1ab-2005";
225 pi2.p_pi_len = strlen(pi2.p_pi);
226 TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi1, p_entries);
227 TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi2, p_entries);
228
229 /* Build packet */
230 n = lldp_send(&test_lldpd, &hardware);
231 if (n != 0) {
232 fail("unable to build packet");
233 return;
234 }
235 if (TAILQ_EMPTY(&pkts)) {
236 fail("no packets sent");
237 return;
238 }
239 pkt = TAILQ_FIRST(&pkts);
240 fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
241
242 /* decode the retrieved packet calling lldp_decode() */
243 fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware,
244 &nchassis, &nport) != -1);
245 if (!nchassis || !nport) {
246 fail("unable to decode packet");
247 return;
248 }
249
250 /* verify port values */
251 check_received_port(&hardware.h_lport, nport);
252 /* verify chassis values */
253 check_received_chassis(&chassis, nchassis);
254
255 if (TAILQ_EMPTY(&nport->p_vlans)) {
256 fail("no VLAN");
257 return;
258 }
259
260 rvlan = TAILQ_FIRST(&nport->p_vlans);
261 ck_assert_int_eq(rvlan->v_vid, vlan1.v_vid);
262 ck_assert_str_eq(rvlan->v_name, vlan1.v_name);
263
264 rvlan = TAILQ_NEXT(rvlan, v_entries);
265 if (!rvlan) {
266 fail("no more VLAN");
267 return;
268 }
269 ck_assert_int_eq(rvlan->v_vid, vlan2.v_vid);
270 ck_assert_str_eq(rvlan->v_name, vlan2.v_name);
271
272 rvlan = TAILQ_NEXT(rvlan, v_entries);
273 if (!rvlan) {
274 fail("no more VLAN");
275 return;
276 }
277 ck_assert_int_eq(rvlan->v_vid, vlan3.v_vid);
278 ck_assert_str_eq(rvlan->v_name, vlan3.v_name);
279
280 rvlan = TAILQ_NEXT(rvlan, v_entries);
281 fail_unless(rvlan == NULL);
282
283 ck_assert_int_eq(nport->p_pvid, hardware.h_lport.p_pvid);
284
285 if (TAILQ_EMPTY(&nport->p_ppvids)) {
286 fail("no Port Protocal VLAN ID");
287 return;
288 }
289 rppvid = TAILQ_FIRST(&nport->p_ppvids);
290 ck_assert_int_eq(rppvid->p_cap_status, ppvid.p_cap_status);
291 ck_assert_int_eq(rppvid->p_ppvid, ppvid.p_ppvid);
292
293 if (TAILQ_EMPTY(&nport->p_pids)) {
294 fail("no Protocal Identity TLV");
295 return;
296 }
297 rpi = TAILQ_FIRST(&nport->p_pids);
298 ck_assert_int_eq(rpi->p_pi_len, pi1.p_pi_len);
299 ck_assert_str_eq_n(rpi->p_pi, pi1.p_pi, pi1.p_pi_len);
300
301 rpi = TAILQ_NEXT(rpi, p_entries);
302 if (!rpi) {
303 fail("no more Protocol Identity TLVs");
304 return;
305 }
306 ck_assert_int_eq(rpi->p_pi_len, pi2.p_pi_len);
307 ck_assert_str_eq_n(rpi->p_pi, pi2.p_pi, pi2.p_pi_len);
308
309 rpi = TAILQ_NEXT(rpi, p_entries);
310 fail_unless(rpi == NULL);
311 }
312 END_TEST
313 #endif
314
315 #ifdef ENABLE_LLDPMED
316 START_TEST (test_send_rcv_med)
317 {
318 int n;
319 struct packet *pkt;
320 struct lldpd_chassis *nchassis = NULL;
321 struct lldpd_port *nport = NULL;
322
323 /* Populate port and chassis */
324 hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR;
325 hardware.h_lport.p_id = macaddress;
326 hardware.h_lport.p_id_len = ETHER_ADDR_LEN;
327 hardware.h_lport.p_descr = "Fake port description";
328 hardware.h_lport.p_mfs = 1516;
329 chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL;
330 chassis.c_id = "Chassis name";
331 chassis.c_id_len = strlen(chassis.c_id);
332 chassis.c_name = "Third chassis";
333 chassis.c_descr = "Chassis description";
334 chassis.c_cap_available = LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE;
335 chassis.c_cap_enabled = LLDP_CAP_ROUTER;
336 chassis.c_med_cap_available = LLDP_MED_CAP_CAP | LLDP_MED_CAP_POLICY |
337 LLDP_MED_CAP_LOCATION | LLDP_MED_CAP_MDI_PSE |
338 LLDP_MED_CAP_IV;
339 chassis.c_med_type = LLDP_MED_CLASS_III;
340 chassis.c_med_hw = "hardware rev 5";
341 chassis.c_med_fw = "47b5";
342 chassis.c_med_sw = "2.6.22b5";
343 chassis.c_med_sn = "SN 47842";
344 hardware.h_lport.p_med_cap_enabled = chassis.c_med_cap_available;
345 hardware.h_lport.p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].format =
346 LLDP_MED_LOCFORMAT_CIVIC;
347 hardware.h_lport.p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data = "Your favorite city";
348 hardware.h_lport.p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data_len =
349 sizeof("Your favorite city");
350 hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].type =
351 LLDP_MED_APPTYPE_SOFTPHONEVOICE;
352 hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].tagged =
353 1;
354 hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].vid =
355 51;
356 hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].priority =
357 6;
358 hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].dscp =
359 46;
360 hardware.h_lport.p_med_power.devicetype = LLDP_MED_POW_TYPE_PSE;
361 hardware.h_lport.p_med_power.source = LLDP_MED_POW_SOURCE_PRIMARY;
362 hardware.h_lport.p_med_power.priority = LLDP_MED_POW_PRIO_HIGH;
363 hardware.h_lport.p_med_power.val = 65;
364
365 /* Build packet */
366 n = lldp_send(&test_lldpd, &hardware);
367 if (n != 0) {
368 fail("unable to build packet");
369 return;
370 }
371 if (TAILQ_EMPTY(&pkts)) {
372 fail("no packets sent");
373 return;
374 }
375 pkt = TAILQ_FIRST(&pkts);
376 fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
377
378 /* decode the retrieved packet calling lldp_decode() */
379 fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware,
380 &nchassis, &nport) != -1);
381 if (!nchassis || !nport) {
382 fail("unable to decode packet");
383 return;
384 }
385 /* verify port values */
386 check_received_port(&hardware.h_lport, nport);
387 /* verify chassis values */
388 check_received_chassis(&chassis, nchassis);
389
390 /* veridfy med content */
391 check_received_port_med(&hardware.h_lport, nport);
392 check_received_chassis_med(&chassis, nchassis);
393 }
394 END_TEST
395 #endif
396
397 #ifdef ENABLE_DOT3
398 START_TEST (test_send_rcv_dot3)
399 {
400 int n;
401 struct lldpd_chassis *nchassis = NULL;
402 struct lldpd_port *nport = NULL;
403 struct packet *pkt;
404
405 /* Populate port and chassis */
406 hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME;
407 hardware.h_lport.p_id = "FastEthernet 1/5";
408 hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id);
409 hardware.h_lport.p_descr = "Fake port description";
410 hardware.h_lport.p_mfs = 1516;
411 hardware.h_lport.p_aggregid = 5;
412 hardware.h_lport.p_macphy.autoneg_support = 1;
413 hardware.h_lport.p_macphy.autoneg_enabled = 1;
414 hardware.h_lport.p_macphy.autoneg_advertised = LLDP_DOT3_LINK_AUTONEG_10BASE_T |
415 LLDP_DOT3_LINK_AUTONEG_10BASET_FD | LLDP_DOT3_LINK_AUTONEG_100BASE_TX |
416 LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD;
417 hardware.h_lport.p_macphy.mau_type = LLDP_DOT3_MAU_100BASETXFD;
418 chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
419 chassis.c_id = macaddress;
420 chassis.c_id_len = ETHER_ADDR_LEN;
421 chassis.c_name = "Fourth chassis";
422 chassis.c_descr = "Long chassis description";
423 chassis.c_cap_available = chassis.c_cap_enabled = LLDP_CAP_ROUTER | LLDP_CAP_WLAN;
424
425 /* Build packet */
426 n = lldp_send(&test_lldpd, &hardware);
427 if (n != 0) {
428 fail("unable to build packet");
429 return;
430 }
431 if (TAILQ_EMPTY(&pkts)) {
432 fail("no packets sent");
433 return;
434 }
435 pkt = TAILQ_FIRST(&pkts);
436 fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
437
438 /* decode the retrieved packet calling lldp_decode() */
439 fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware,
440 &nchassis, &nport) != -1);
441 if (!nchassis || !nport) {
442 fail("unable to decode packet");
443 return;
444 }
445 /* verify port values */
446 check_received_port(&hardware.h_lport, nport);
447 /* verify chassis values */
448 check_received_chassis(&chassis, nchassis);
449 /* verify dot3 values */
450 check_received_port_dot3(&hardware.h_lport, nport);
451 }
452 END_TEST
453 #endif
454
455 START_TEST (test_recv_min)
456 {
457 char pkt1[] = {
458 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x17,
459 0xd1, 0xa8, 0x35, 0xbe, 0x88, 0xcc, 0x02, 0x07,
460 0x04, 0x00, 0x17, 0xd1, 0xa8, 0x35, 0xbf, 0x04,
461 0x07, 0x03, 0x00, 0x17, 0xd1, 0xa8, 0x36, 0x02,
462 0x06, 0x02, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x00, 0x00, 0x00, 0x00 };
466 /* This is:
467 Ethernet II, Src: Nortel_a8:35:be (00:17:d1:a8:35:be), Dst: LLDP_Multicast (01:80:c2:00:00:0e)
468 Destination: LLDP_Multicast (01:80:c2:00:00:0e)
469 Source: Nortel_a8:35:be (00:17:d1:a8:35:be)
470 Type: 802.1 Link Layer Discovery Protocol (LLDP) (0x88cc)
471 Link Layer Discovery Protocol
472 Chassis Subtype = MAC address
473 0000 001. .... .... = TLV Type: Chassis Id (1)
474 .... ...0 0000 0111 = TLV Length: 7
475 Chassis Id Subtype: MAC address (4)
476 Chassis Id: Nortel_a8:35:bf (00:17:d1:a8:35:bf)
477 Port Subtype = MAC address
478 0000 010. .... .... = TLV Type: Port Id (2)
479 .... ...0 0000 0111 = TLV Length: 7
480 Port Id Subtype: MAC address (3)
481 Port Id: Nortel_a8:36:02 (00:17:d1:a8:36:02)
482 Time To Live = 120 sec
483 0000 011. .... .... = TLV Type: Time to Live (3)
484 .... ...0 0000 0010 = TLV Length: 2
485 Seconds: 120
486 End of LLDPDU
487 0000 000. .... .... = TLV Type: End of LLDPDU (0)
488 .... ...0 0000 0000 = TLV Length: 0
489 */
490 struct lldpd_chassis *nchassis = NULL;
491 struct lldpd_port *nport = NULL;
492 char mac1[] = { 0x0, 0x17, 0xd1, 0xa8, 0x35, 0xbf };
493 char mac2[] = { 0x0, 0x17, 0xd1, 0xa8, 0x36, 0x02 };
494
495 fail_unless(lldp_decode(NULL, pkt1, sizeof(pkt1), &hardware,
496 &nchassis, &nport) != -1);
497 if (!nchassis || !nport) {
498 fail("unable to decode packet");
499 return;
500 }
501 ck_assert_int_eq(nchassis->c_id_subtype,
502 LLDP_CHASSISID_SUBTYPE_LLADDR);
503 ck_assert_int_eq(nchassis->c_id_len, ETHER_ADDR_LEN);
504 fail_unless(memcmp(mac1, nchassis->c_id, ETHER_ADDR_LEN) == 0);
505 ck_assert_int_eq(nport->p_id_subtype,
506 LLDP_PORTID_SUBTYPE_LLADDR);
507 ck_assert_int_eq(nport->p_id_len, ETHER_ADDR_LEN);
508 fail_unless(memcmp(mac2, nport->p_id, ETHER_ADDR_LEN) == 0);
509 ck_assert_ptr_eq(nchassis->c_name, NULL);
510 ck_assert_ptr_eq(nchassis->c_descr, NULL);
511 ck_assert_ptr_eq(nport->p_descr, NULL);
512 ck_assert_int_eq(nport->p_ttl, 120);
513 }
514 END_TEST
515
516 START_TEST (test_recv_lldpd)
517 {
518 /* This is a frame generated by lldpd */
519 char pkt1[] = {
520 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x16,
521 0x17, 0x2f, 0xa1, 0xb6, 0x88, 0xcc, 0x02, 0x07,
522 0x04, 0x00, 0x16, 0x17, 0x2f, 0xa1, 0xb6, 0x04,
523 0x07, 0x03, 0x00, 0x16, 0x17, 0x2f, 0xa1, 0xb6,
524 0x06, 0x02, 0x00, 0x78, 0x0a, 0x1a, 0x6e, 0x61,
525 0x72, 0x75, 0x74, 0x6f, 0x2e, 0x58, 0x58, 0x58,
526 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
527 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
528 0x0c, 0x3f, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20,
529 0x32, 0x2e, 0x36, 0x2e, 0x32, 0x39, 0x2d, 0x32,
530 0x2d, 0x61, 0x6d, 0x64, 0x36, 0x34, 0x20, 0x23,
531 0x31, 0x20, 0x53, 0x4d, 0x50, 0x20, 0x53, 0x75,
532 0x6e, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x31, 0x37,
533 0x20, 0x31, 0x37, 0x3a, 0x31, 0x35, 0x3a, 0x34,
534 0x37, 0x20, 0x55, 0x54, 0x43, 0x20, 0x32, 0x30,
535 0x30, 0x39, 0x20, 0x78, 0x38, 0x36, 0x5f, 0x36,
536 0x34, 0x0e, 0x04, 0x00, 0x1c, 0x00, 0x14, 0x10,
537 0x0c, 0x05, 0x01, 0x0a, 0xee, 0x50, 0x4b, 0x02,
538 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x04, 0x65,
539 0x74, 0x68, 0x30, 0xfe, 0x09, 0x00, 0x12, 0x0f,
540 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x09,
541 0x00, 0x12, 0x0f, 0x01, 0x03, 0x6c, 0x03, 0x00,
542 0x10, 0xfe, 0x06, 0x00, 0x12, 0x0f, 0x04, 0x05,
543 0xdc, 0xfe, 0x07, 0x00, 0x12, 0xbb, 0x01, 0x00,
544 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x12, 0xbb, 0x05,
545 0x4e, 0x44, 0x39, 0x39, 0x31, 0x37, 0x38, 0x39,
546 0x37, 0x30, 0x32, 0xfe, 0x0b, 0x00, 0x12, 0xbb,
547 0x06, 0x30, 0x38, 0x30, 0x30, 0x31, 0x32, 0x20,
548 0xfe, 0x12, 0x00, 0x12, 0xbb, 0x07, 0x32, 0x2e,
549 0x36, 0x2e, 0x32, 0x39, 0x2d, 0x32, 0x2d, 0x61,
550 0x6d, 0x64, 0x36, 0x34, 0xfe, 0x10, 0x00, 0x12,
551 0xbb, 0x08, 0x31, 0x30, 0x35, 0x38, 0x32, 0x30,
552 0x38, 0x35, 0x30, 0x30, 0x30, 0x39, 0xfe, 0x15,
553 0x00, 0x12, 0xbb, 0x09, 0x4e, 0x45, 0x43, 0x20,
554 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72,
555 0x73, 0x20, 0x53, 0x41, 0x53, 0xfe, 0x13, 0x00,
556 0x12, 0xbb, 0x0a, 0x50, 0x4f, 0x57, 0x45, 0x52,
557 0x4d, 0x41, 0x54, 0x45, 0x20, 0x56, 0x4c, 0x33,
558 0x35, 0x30, 0xfe, 0x0d, 0x00, 0x12, 0xbb, 0x0b,
559 0x31, 0x30, 0x30, 0x32, 0x30, 0x37, 0x31, 0x32,
560 0x30, 0x00, 0x00 };
561 /* This is:
562 Ethernet II, Src: Msi_2f:a1:b6 (00:16:17:2f:a1:b6), Dst: LLDP_Multicast (01:80:c2:00:00:0e)
563 Destination: LLDP_Multicast (01:80:c2:00:00:0e)
564 Source: Msi_2f:a1:b6 (00:16:17:2f:a1:b6)
565 Type: 802.1 Link Layer Discovery Protocol (LLDP) (0x88cc)
566 Link Layer Discovery Protocol
567 Chassis Subtype = MAC address
568 0000 001. .... .... = TLV Type: Chassis Id (1)
569 .... ...0 0000 0111 = TLV Length: 7
570 Chassis Id Subtype: MAC address (4)
571 Chassis Id: Msi_2f:a1:b6 (00:16:17:2f:a1:b6)
572 Port Subtype = MAC address
573 0000 010. .... .... = TLV Type: Port Id (2)
574 .... ...0 0000 0111 = TLV Length: 7
575 Port Id Subtype: MAC address (3)
576 Port Id: Msi_2f:a1:b6 (00:16:17:2f:a1:b6)
577 Time To Live = 120 sec
578 0000 011. .... .... = TLV Type: Time to Live (3)
579 .... ...0 0000 0010 = TLV Length: 2
580 Seconds: 120
581 System Name = naruto.XXXXXXXXXXXXXXXXXXX
582 0000 101. .... .... = TLV Type: System Name (5)
583 .... ...0 0001 1010 = TLV Length: 26
584 System Name = naruto.bureau.b1.p.fti.net
585 System Description = Linux 2.6.29-2-amd64 #1 SMP Sun May 17 17:15:47 UTC 2009 x86_64
586 0000 110. .... .... = TLV Type: System Description (6)
587 .... ...0 0011 1111 = TLV Length: 63
588 System Description = Linux 2.6.29-2-amd64 #1 SMP Sun May 17 17:15:47 UTC 2009 x86_64
589 Capabilities
590 0000 111. .... .... = TLV Type: System Capabilities (7)
591 .... ...0 0000 0100 = TLV Length: 4
592 Capabilities: 0x001c
593 .... .... .... .1.. = Bridge
594 .... .... .... 1... = WLAN access point
595 .... .... ...1 .... = Router
596 Enabled Capabilities: 0x0014
597 .... .... .... .1.. = Bridge
598 .... .... ...1 .... = Router
599 Management Address
600 0001 000. .... .... = TLV Type: Management Address (8)
601 .... ...0 0000 1100 = TLV Length: 12
602 Address String Length: 5
603 Address Subtype: IPv4 (1)
604 Management Address: 10.238.80.75
605 Interface Subtype: ifIndex (2)
606 Interface Number: 3
607 OID String Length: 0
608 Port Description = eth0
609 0000 100. .... .... = TLV Type: Port Description (4)
610 .... ...0 0000 0100 = TLV Length: 4
611 Port Description: eth0
612 IEEE 802.3 - Link Aggregation
613 1111 111. .... .... = TLV Type: Organization Specific (127)
614 .... ...0 0000 1001 = TLV Length: 9
615 Organization Unique Code: IEEE 802.3 (0x00120f)
616 IEEE 802.3 Subtype: Link Aggregation (0x03)
617 Aggregation Status: 0x01
618 .... ...1 = Aggregation Capability: Yes
619 .... ..0. = Aggregation Status: Not Enabled
620 Aggregated Port Id: 0
621 IEEE 802.3 - MAC/PHY Configuration/Status
622 1111 111. .... .... = TLV Type: Organization Specific (127)
623 .... ...0 0000 1001 = TLV Length: 9
624 Organization Unique Code: IEEE 802.3 (0x00120f)
625 IEEE 802.3 Subtype: MAC/PHY Configuration/Status (0x01)
626 Auto-Negotiation Support/Status: 0x03
627 .... ...1 = Auto-Negotiation: Supported
628 .... ..1. = Auto-Negotiation: Enabled
629 PMD Auto-Negotiation Advertised Capability: 0x6C03
630 .... .... .... ...1 = 1000BASE-T (full duplex mode)
631 .... .... .... ..1. = 1000BASE-T (half duplex mode)
632 .... .1.. .... .... = 100BASE-TX (full duplex mode)
633 .... 1... .... .... = 100BASE-TX (half duplex mode)
634 ..1. .... .... .... = 10BASE-T (full duplex mode)
635 .1.. .... .... .... = 10BASE-T (half duplex mode)
636 Operational MAU Type: 100BaseTXFD - 2 pair category 5 UTP, full duplex mode (0x0010)
637 IEEE 802.3 - Maximum Frame Size
638 1111 111. .... .... = TLV Type: Organization Specific (127)
639 .... ...0 0000 0110 = TLV Length: 6
640 Organization Unique Code: IEEE 802.3 (0x00120f)
641 IEEE 802.3 Subtype: Maximum Frame Size (0x04)
642 Maximum Frame Size: 1500
643 TIA - Media Capabilities
644 1111 111. .... .... = TLV Type: Organization Specific (127)
645 .... ...0 0000 0111 = TLV Length: 7
646 Organization Unique Code: TIA (0x0012bb)
647 Media Subtype: Media Capabilities (0x01)
648 Capabilities: 0x0000
649 Class Type: Type Not Defined
650 TIA - Inventory - Hardware Revision
651 1111 111. .... .... = TLV Type: Organization Specific (127)
652 .... ...0 0000 1111 = TLV Length: 15
653 Organization Unique Code: TIA (0x0012bb)
654 Media Subtype: Inventory - Hardware Revision (0x05)
655 Hardware Revision: ND991789702
656 TIA - Inventory - Firmware Revision
657 1111 111. .... .... = TLV Type: Organization Specific (127)
658 .... ...0 0000 1011 = TLV Length: 10
659 Organization Unique Code: TIA (0x0012bb)
660 Media Subtype: Inventory - Firmware Revision (0x06)
661 Firmware Revision: 080012
662 TIA - Inventory - Software Revision
663 1111 111. .... .... = TLV Type: Organization Specific (127)
664 .... ...0 0001 0010 = TLV Length: 18
665 Organization Unique Code: TIA (0x0012bb)
666 Media Subtype: Inventory - Software Revision (0x07)
667 Software Revision: 2.6.29-2-amd64
668 TIA - Inventory - Serial Number
669 1111 111. .... .... = TLV Type: Organization Specific (127)
670 .... ...0 0001 0000 = TLV Length: 16
671 Organization Unique Code: TIA (0x0012bb)
672 Media Subtype: Inventory - Serial Number (0x08)
673 Serial Number: 105820850009
674 TIA - Inventory - Manufacturer Name
675 1111 111. .... .... = TLV Type: Organization Specific (127)
676 .... ...0 0001 0101 = TLV Length: 21
677 Organization Unique Code: TIA (0x0012bb)
678 Media Subtype: Inventory - Manufacturer Name (0x09)
679 Manufacturer Name: NEC Computers SAS
680 TIA - Inventory - Model Name
681 1111 111. .... .... = TLV Type: Organization Specific (127)
682 .... ...0 0001 0011 = TLV Length: 19
683 Organization Unique Code: TIA (0x0012bb)
684 Media Subtype: Inventory - Model Name (0x0a)
685 Model Name: POWERMATE VL350
686 TIA - Inventory - Asset ID
687 1111 111. .... .... = TLV Type: Organization Specific (127)
688 .... ...0 0000 1101 = TLV Length: 13
689 Organization Unique Code: TIA (0x0012bb)
690 Media Subtype: Inventory - Asset ID (0x0b)
691 Asset ID: 100207120
692 End of LLDPDU
693 0000 000. .... .... = TLV Type: End of LLDPDU (0)
694 .... ...0 0000 0000 = TLV Length: 0
695 */
696 struct lldpd_chassis *nchassis = NULL;
697 struct lldpd_port *nport = NULL;
698 char mac1[] = { 0x00, 0x16, 0x17, 0x2f, 0xa1, 0xb6 };
699
700 fail_unless(lldp_decode(NULL, pkt1, sizeof(pkt1), &hardware,
701 &nchassis, &nport) != -1);
702 if (!nchassis || !nport) {
703 fail("unable to decode packet");
704 return;
705 }
706 ck_assert_int_eq(nchassis->c_id_subtype,
707 LLDP_CHASSISID_SUBTYPE_LLADDR);
708 ck_assert_int_eq(nchassis->c_id_len, ETHER_ADDR_LEN);
709 fail_unless(memcmp(mac1, nchassis->c_id, ETHER_ADDR_LEN) == 0);
710 ck_assert_int_eq(nport->p_id_subtype,
711 LLDP_PORTID_SUBTYPE_LLADDR);
712 ck_assert_int_eq(nport->p_id_len, ETHER_ADDR_LEN);
713 fail_unless(memcmp(mac1, nport->p_id, ETHER_ADDR_LEN) == 0);
714 ck_assert_int_eq(nport->p_ttl, 120);
715 ck_assert_str_eq(nchassis->c_name, "naruto.XXXXXXXXXXXXXXXXXXX");
716 ck_assert_str_eq(nchassis->c_descr,
717 "Linux 2.6.29-2-amd64 #1 SMP Sun May 17 17:15:47 UTC 2009 x86_64");
718 ck_assert_str_eq(nport->p_descr, "eth0");
719 ck_assert_int_eq(nchassis->c_cap_available,
720 LLDP_CAP_WLAN | LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE);
721 ck_assert_int_eq(nchassis->c_cap_enabled,
722 LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE);
723 ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_addr.inet.s_addr,
724 (u_int32_t)inet_addr("10.238.80.75"));
725 ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_iface, 3);
726 #ifdef ENABLE_DOT3
727 ck_assert_int_eq(nport->p_aggregid, 0);
728 ck_assert_int_eq(nport->p_macphy.autoneg_enabled, 1);
729 ck_assert_int_eq(nport->p_macphy.autoneg_support, 1);
730 ck_assert_int_eq(nport->p_macphy.autoneg_advertised,
731 LLDP_DOT3_LINK_AUTONEG_1000BASE_TFD |
732 LLDP_DOT3_LINK_AUTONEG_1000BASE_T |
733 LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD |
734 LLDP_DOT3_LINK_AUTONEG_100BASE_TX |
735 LLDP_DOT3_LINK_AUTONEG_10BASET_FD |
736 LLDP_DOT3_LINK_AUTONEG_10BASE_T);
737 ck_assert_int_eq(nport->p_macphy.mau_type,
738 LLDP_DOT3_MAU_100BASETXFD);
739 ck_assert_int_eq(nport->p_mfs, 1500);
740 #endif
741 #ifdef ENABLE_LLDPMED
742 ck_assert_int_eq(nchassis->c_med_type, 0);
743 ck_assert_str_eq(nchassis->c_med_hw, "ND991789702");
744 ck_assert_str_eq(nchassis->c_med_fw, "080012 "); /* Extra space */
745 ck_assert_str_eq(nchassis->c_med_sw, "2.6.29-2-amd64");
746 ck_assert_str_eq(nchassis->c_med_sn, "105820850009");
747 ck_assert_str_eq(nchassis->c_med_manuf, "NEC Computers SAS");
748 ck_assert_str_eq(nchassis->c_med_model, "POWERMATE VL350");
749 ck_assert_str_eq(nchassis->c_med_asset, "100207120");
750 #endif
751 }
752 END_TEST
753
754 Suite *
755 lldp_suite(void)
756 {
757 Suite *s = suite_create("LLDP");
758 TCase *tc_send = tcase_create("Send LLDP packets");
759 TCase *tc_receive = tcase_create("Receive LLDP packets");
760
761 /* Send tests are first run without knowing the result. The
762 result is then checked with:
763 tshark -V -T text -r tests/lldp_send_0000.pcap
764
765 If the result is correct, then, we get the packet as C
766 bytes using wireshark export to C arrays (tshark seems not
767 be able to do this).
768 */
769
770 tcase_add_checked_fixture(tc_send, pcap_setup, pcap_teardown);
771 tcase_add_test(tc_send, test_send_rcv_basic);
772 #ifdef ENABLE_DOT1
773 tcase_add_test(tc_send, test_send_rcv_dot1_tlvs);
774 #endif
775 #ifdef ENABLE_LLDPMED
776 tcase_add_test(tc_send, test_send_rcv_med);
777 #endif
778 #ifdef ENABLE_DOT3
779 tcase_add_test(tc_send, test_send_rcv_dot3);
780 #endif
781 suite_add_tcase(s, tc_send);
782
783 tcase_add_test(tc_receive, test_recv_min);
784 tcase_add_test(tc_receive, test_recv_lldpd);
785 suite_add_tcase(s, tc_receive);
786
787 return s;
788 }
789
790 int
791 main()
792 {
793 int number_failed;
794 Suite *s = lldp_suite ();
795 SRunner *sr = srunner_create (s);
796 srunner_set_fork_status (sr, CK_NOFORK); /* Can't fork because
797 we need to write
798 files */
799 srunner_run_all (sr, CK_ENV);
800 number_failed = srunner_ntests_failed (sr);
801 srunner_free (sr);
802 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
803 }