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