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