]> git.ipfire.org Git - thirdparty/lldpd.git/blame - tests/check_lldp.c
tests: display tests/test-suite.log on errors
[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}
50
51static void
52check_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);
bc99d796 57 ck_assert_int_eq(rchassis->c_id_len, schassis->c_id_len);
0c0991d8 58 ck_assert_str_eq_n(rchassis->c_id, schassis->c_id, schassis->c_id_len);
bc99d796
SK
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);
bc99d796
SK
63}
64
65#ifdef ENABLE_LLDPMED
66static void
67check_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(
4b292b55
VB
74 rport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].format,
75 sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].format);
bc99d796 76 ck_assert_int_eq(
4b292b55
VB
77 rport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data_len,
78 sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC-1].data_len);
0c0991d8 79 ck_assert_str_eq_n(
4b292b55
VB
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);
bc99d796 83 ck_assert_int_eq(
4b292b55
VB
84 rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].type,
85 sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].type);
bc99d796 86 ck_assert_int_eq(
4b292b55
VB
87 rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].tagged,
88 sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].tagged);
bc99d796 89 ck_assert_int_eq(
4b292b55
VB
90 rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].vid,
91 sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].vid);
bc99d796 92 ck_assert_int_eq(
4b292b55
VB
93 rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].priority,
94 sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].priority);
bc99d796 95 ck_assert_int_eq(
4b292b55
VB
96 rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].dscp,
97 sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].dscp);
bc99d796
SK
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);
bc99d796
SK
104}
105
106static void
107check_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);
bc99d796
SK
118}
119#endif
120
31375299 121#ifdef ENABLE_DOT3
bc99d796
SK
122static void
123check_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);
bc99d796 135}
31375299 136#endif
bc99d796
SK
137
138START_TEST (test_send_rcv_basic)
139{
140 int n;
fedf4d77 141 struct packet *pkt;
bc99d796
SK
142 struct lldpd_chassis *nchassis = NULL;
143 struct lldpd_port *nport = NULL;
fedf4d77
VB
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;
4e5f34c5 153 chassis.c_id_len = ETHER_ADDR_LEN;
fedf4d77
VB
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 */
1d7c86b5 159 n = lldp_send(&test_lldpd, &hardware);
9360858c
VB
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 }
fedf4d77 168 pkt = TAILQ_FIRST(&pkts);
fedf4d77 169 fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
bc99d796
SK
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);
fedf4d77
VB
182}
183END_TEST
184
31375299 185#ifdef ENABLE_DOT1
bc99d796
SK
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 */
189START_TEST (test_send_rcv_dot1_tlvs)
fedf4d77
VB
190{
191 int n;
bc99d796
SK
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;
fedf4d77
VB
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;
4e5f34c5 202 hardware.h_lport.p_id_len = ETHER_ADDR_LEN;
fedf4d77
VB
203 hardware.h_lport.p_descr = "Fake port description";
204 hardware.h_lport.p_mfs = 1516;
bc99d796 205 hardware.h_lport.p_pvid = 1500;
fedf4d77
VB
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;
bc99d796
SK
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;
fedf4d77
VB
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);
bc99d796
SK
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";
de5ce837 223 pi1.p_pi_len = strlen(pi1.p_pi);
bc99d796 224 pi2.p_pi = "IEEE Link Layer Discovery Protocol 802.1ab-2005";
de5ce837 225 pi2.p_pi_len = strlen(pi2.p_pi);
bc99d796
SK
226 TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi1, p_entries);
227 TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi2, p_entries);
fedf4d77
VB
228
229 /* Build packet */
1d7c86b5 230 n = lldp_send(&test_lldpd, &hardware);
9360858c
VB
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 }
fedf4d77 239 pkt = TAILQ_FIRST(&pkts);
fedf4d77 240 fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
bc99d796
SK
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);
0c0991d8
VB
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);
bc99d796
SK
300
301 rpi = TAILQ_NEXT(rpi, p_entries);
302 if (!rpi) {
303 fail("no more Protocol Identity TLVs");
304 return;
305 }
0c0991d8
VB
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);
bc99d796
SK
308
309 rpi = TAILQ_NEXT(rpi, p_entries);
310 fail_unless(rpi == NULL);
fedf4d77
VB
311}
312END_TEST
31375299 313#endif
fedf4d77 314
31375299 315#ifdef ENABLE_LLDPMED
bc99d796 316START_TEST (test_send_rcv_med)
fedf4d77
VB
317{
318 int n;
fedf4d77 319 struct packet *pkt;
bc99d796
SK
320 struct lldpd_chassis *nchassis = NULL;
321 struct lldpd_port *nport = NULL;
fedf4d77
VB
322
323 /* Populate port and chassis */
324 hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR;
325 hardware.h_lport.p_id = macaddress;
4e5f34c5 326 hardware.h_lport.p_id_len = ETHER_ADDR_LEN;
fedf4d77
VB
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;
4b292b55
VB
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;
fedf4d77
VB
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;
4b292b55
VB
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 =
bc99d796 349 sizeof("Your favorite city");
4b292b55
VB
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 =
fedf4d77 353 1;
4b292b55 354 hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].vid =
fedf4d77 355 51;
4b292b55 356 hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].priority =
fedf4d77 357 6;
4b292b55 358 hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE-1].dscp =
fedf4d77 359 46;
4b292b55
VB
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;
6d08df0e 363 hardware.h_lport.p_med_power.val = 65;
fedf4d77
VB
364
365 /* Build packet */
1d7c86b5 366 n = lldp_send(&test_lldpd, &hardware);
9360858c
VB
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 }
fedf4d77 375 pkt = TAILQ_FIRST(&pkts);
fedf4d77 376 fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
bc99d796
SK
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);
fedf4d77
VB
393}
394END_TEST
31375299 395#endif
fedf4d77 396
31375299 397#ifdef ENABLE_DOT3
bc99d796 398START_TEST (test_send_rcv_dot3)
fedf4d77
VB
399{
400 int n;
bc99d796
SK
401 struct lldpd_chassis *nchassis = NULL;
402 struct lldpd_port *nport = NULL;
fedf4d77
VB
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;
3fd015c0
VB
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 |
fedf4d77
VB
415 LLDP_DOT3_LINK_AUTONEG_10BASET_FD | LLDP_DOT3_LINK_AUTONEG_100BASE_TX |
416 LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD;
3fd015c0 417 hardware.h_lport.p_macphy.mau_type = LLDP_DOT3_MAU_100BASETXFD;
fedf4d77
VB
418 chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
419 chassis.c_id = macaddress;
4e5f34c5 420 chassis.c_id_len = ETHER_ADDR_LEN;
fedf4d77
VB
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 */
1d7c86b5 426 n = lldp_send(&test_lldpd, &hardware);
9360858c
VB
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 }
fedf4d77 435 pkt = TAILQ_FIRST(&pkts);
fedf4d77 436 fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent");
bc99d796
SK
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);
fedf4d77
VB
451}
452END_TEST
31375299 453#endif
fedf4d77 454
654f6246
VB
455START_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:
467Ethernet 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)
471Link 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);
9360858c
VB
497 if (!nchassis || !nport) {
498 fail("unable to decode packet");
499 return;
500 }
654f6246
VB
501 ck_assert_int_eq(nchassis->c_id_subtype,
502 LLDP_CHASSISID_SUBTYPE_LLADDR);
4e5f34c5
VB
503 ck_assert_int_eq(nchassis->c_id_len, ETHER_ADDR_LEN);
504 fail_unless(memcmp(mac1, nchassis->c_id, ETHER_ADDR_LEN) == 0);
654f6246
VB
505 ck_assert_int_eq(nport->p_id_subtype,
506 LLDP_PORTID_SUBTYPE_LLADDR);
4e5f34c5
VB
507 ck_assert_int_eq(nport->p_id_len, ETHER_ADDR_LEN);
508 fail_unless(memcmp(mac2, nport->p_id, ETHER_ADDR_LEN) == 0);
a0cd2b9a
VB
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);
78346c89 512 ck_assert_int_eq(nport->p_ttl, 120);
654f6246
VB
513}
514END_TEST
515
516START_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:
562Ethernet 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)
566Link 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);
9360858c
VB
702 if (!nchassis || !nport) {
703 fail("unable to decode packet");
704 return;
705 }
654f6246
VB
706 ck_assert_int_eq(nchassis->c_id_subtype,
707 LLDP_CHASSISID_SUBTYPE_LLADDR);
4e5f34c5
VB
708 ck_assert_int_eq(nchassis->c_id_len, ETHER_ADDR_LEN);
709 fail_unless(memcmp(mac1, nchassis->c_id, ETHER_ADDR_LEN) == 0);
654f6246
VB
710 ck_assert_int_eq(nport->p_id_subtype,
711 LLDP_PORTID_SUBTYPE_LLADDR);
4e5f34c5
VB
712 ck_assert_int_eq(nport->p_id_len, ETHER_ADDR_LEN);
713 fail_unless(memcmp(mac1, nport->p_id, ETHER_ADDR_LEN) == 0);
78346c89 714 ck_assert_int_eq(nport->p_ttl, 120);
654f6246
VB
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);
e6b36c87 723 ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_addr.inet.s_addr,
654f6246 724 (u_int32_t)inet_addr("10.238.80.75"));
e6b36c87 725 ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_iface, 3);
31375299 726#ifdef ENABLE_DOT3
654f6246 727 ck_assert_int_eq(nport->p_aggregid, 0);
3fd015c0
VB
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,
654f6246
VB
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);
3fd015c0 737 ck_assert_int_eq(nport->p_macphy.mau_type,
654f6246
VB
738 LLDP_DOT3_MAU_100BASETXFD);
739 ck_assert_int_eq(nport->p_mfs, 1500);
31375299
VB
740#endif
741#ifdef ENABLE_LLDPMED
654f6246
VB
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");
31375299 750#endif
654f6246
VB
751}
752END_TEST
753
fedf4d77
VB
754Suite *
755lldp_suite(void)
756{
757 Suite *s = suite_create("LLDP");
5fd6695c
VB
758 TCase *tc_send = tcase_create("Send LLDP packets");
759 TCase *tc_receive = tcase_create("Receive LLDP packets");
fedf4d77
VB
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
4dc61015 770 tcase_add_checked_fixture(tc_send, pcap_setup, pcap_teardown);
bc99d796 771 tcase_add_test(tc_send, test_send_rcv_basic);
31375299 772#ifdef ENABLE_DOT1
bc99d796 773 tcase_add_test(tc_send, test_send_rcv_dot1_tlvs);
31375299
VB
774#endif
775#ifdef ENABLE_LLDPMED
bc99d796 776 tcase_add_test(tc_send, test_send_rcv_med);
31375299
VB
777#endif
778#ifdef ENABLE_DOT3
bc99d796 779 tcase_add_test(tc_send, test_send_rcv_dot3);
31375299 780#endif
fedf4d77
VB
781 suite_add_tcase(s, tc_send);
782
654f6246
VB
783 tcase_add_test(tc_receive, test_recv_min);
784 tcase_add_test(tc_receive, test_recv_lldpd);
fedf4d77
VB
785 suite_add_tcase(s, tc_receive);
786
787 return s;
788}
789
790int
791main()
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}