]>
git.ipfire.org Git - thirdparty/lldpd.git/blob - tests/decode.c
1 /* -*- mode: c; c-file-style: "openbsd" -*- */
3 * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx>
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.
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.
21 #include <sys/types.h>
24 #include <arpa/inet.h>
29 char filenameprefix
[] = "decode";
34 fprintf(stderr
, "Usage: %s PCAP\n", "decode");
35 fprintf(stderr
, "Version: %s\n", PACKAGE_STRING
);
37 fprintf(stderr
, "\n");
39 fprintf(stderr
, "Decode content of PCAP files and display a summary\n");
40 fprintf(stderr
, "on standard output. Only the first packet is decoded.\n");
45 tohex(char *str
, size_t len
)
47 static char *hex
= NULL
;
48 free(hex
); hex
= NULL
;
49 if ((hex
= malloc(len
* 3 + 1)) == NULL
) return NULL
;
50 for (size_t i
= 0; i
< len
; i
++)
51 snprintf(hex
+ 3*i
, 4, "%02X ", (unsigned char)str
[i
]);
55 /* We need an assert macro which doesn't abort */
56 #define assert(x) while (!(x)) { \
57 fprintf(stderr, "%s:%d: %s: Assertion `%s' failed.\n", \
58 __FILE__, __LINE__, __func__, #x); \
63 main(int argc
, char **argv
)
66 !strcmp(argv
[1], "-h") ||
67 !strcmp(argv
[1], "--help"))
70 int fd
= open(argv
[1], O_RDONLY
);
74 ssize_t len
= read(fd
, buf
, BUFSIZE
);
78 assert(len
>= sizeof(hdr
));
79 memcpy(&hdr
, buf
, sizeof(hdr
));
80 assert(hdr
.magic_number
== 0xa1b2c3d4); /* Assume the same byte order as us */
81 assert(hdr
.version_major
== 2);
82 assert(hdr
.version_minor
== 4);
83 assert(hdr
.thiszone
== 0);
84 /* Don't care about other flags */
86 struct pcaprec_hdr rechdr
;
87 assert(len
>= sizeof(hdr
) + sizeof(rechdr
));
88 memcpy(&rechdr
, buf
+ sizeof(hdr
), sizeof(rechdr
));
89 assert(len
>= sizeof(hdr
) + sizeof(rechdr
) + rechdr
.incl_len
);
91 /* For decoding, we only need a very basic hardware */
92 struct lldpd_hardware hardware
;
93 memset(&hardware
, 0, sizeof(struct lldpd_hardware
));
94 hardware
.h_mtu
= 1500;
95 strlcpy(hardware
.h_ifname
, "test", sizeof(hardware
.h_ifname
));
97 char *frame
= buf
+ sizeof(hdr
) + sizeof(rechdr
);
98 struct lldpd_chassis
*nchassis
= NULL
;
99 struct lldpd_port
*nport
= NULL
;
101 if (lldp_decode(NULL
, frame
, rechdr
.incl_len
, &hardware
, &nchassis
, &nport
) == -1) {
102 fprintf(stderr
, "Not decoded as a LLDP frame\n");
104 fprintf(stderr
, "Decoded as a LLDP frame\n");
107 #if defined ENABLE_CDP || defined ENABLE_FDP
108 if (cdp_decode(NULL
, frame
, rechdr
.incl_len
, &hardware
, &nchassis
, &nport
) == -1) {
109 fprintf(stderr
, "Not decoded as a CDP frame\n");
111 fprintf(stderr
, "Decoded as a CDP frame\n");
116 if (sonmp_decode(NULL
, frame
, rechdr
.incl_len
, &hardware
, &nchassis
, &nport
) == -1) {
117 fprintf(stderr
, "Not decoded as a SONMP frame\n");
119 fprintf(stderr
, "Decoded as a SONMP frame\n");
124 if (edp_decode(NULL
, frame
, rechdr
.incl_len
, &hardware
, &nchassis
, &nport
) == -1) {
125 fprintf(stderr
, "Not decoded as a EDP frame\n");
127 fprintf(stderr
, "Decoded as a EDP frame\n");
131 if (!decoded
) exit(1);
133 printf("Chassis:\n");
134 printf(" Index: %" PRIu16
"\n", nchassis
->c_index
);
135 printf(" Protocol: %" PRIu8
"\n", nchassis
->c_protocol
);
136 printf(" ID subtype: %" PRIu8
"\n", nchassis
->c_id_subtype
);
137 printf(" ID: %s\n", tohex(nchassis
->c_id
, nchassis
->c_id_len
));
138 printf(" Name: %s\n", nchassis
->c_name
?nchassis
->c_name
:"(null)");
139 printf(" Description: %s\n", nchassis
->c_descr
?nchassis
->c_descr
:"(null)");
140 printf(" Cap available: %" PRIu16
"\n", nchassis
->c_cap_available
);
141 printf(" Cap enabled: %" PRIu16
"\n", nchassis
->c_cap_enabled
);
142 struct lldpd_mgmt
*mgmt
;
143 TAILQ_FOREACH(mgmt
, &nchassis
->c_mgmt
, m_entries
) {
144 char ipaddress
[INET6_ADDRSTRLEN
+ 1];
146 switch (mgmt
->m_family
) {
148 alen
= INET_ADDRSTRLEN
+ 1;
152 alen
= INET6_ADDRSTRLEN
+ 1;
158 if (len
== 0) continue;
159 if (inet_ntop(af
, &mgmt
->m_addr
, ipaddress
, alen
) == NULL
)
161 printf(" mgmt: %s\n", ipaddress
);
163 #ifdef ENABLE_LLDPMED
164 printf(" MED cap: %" PRIu16
"\n", nchassis
->c_med_cap_available
);
165 printf(" MED type: %" PRIu8
"\n", nchassis
->c_med_type
);
166 printf(" MED HW: %s\n", nchassis
->c_med_hw
?nchassis
->c_med_hw
:"(null)");
167 printf(" MED FW: %s\n", nchassis
->c_med_fw
?nchassis
->c_med_fw
:"(null)");
168 printf(" MED SW: %s\n", nchassis
->c_med_sw
?nchassis
->c_med_sw
:"(null)");
169 printf(" MED SN: %s\n", nchassis
->c_med_sn
?nchassis
->c_med_sn
:"(null)");
170 printf(" MED manufacturer: %s\n", nchassis
->c_med_manuf
?nchassis
->c_med_manuf
:"(null)");
171 printf(" MED model: %s\n", nchassis
->c_med_model
?nchassis
->c_med_model
:"(null)");
172 printf(" MED asset: %s\n", nchassis
->c_med_asset
?nchassis
->c_med_asset
:"(null)");
176 printf(" ID subtype: %" PRIu8
"\n", nport
->p_id_subtype
);
177 printf(" ID: %s\n", tohex(nport
->p_id
, nport
->p_id_len
));
178 printf(" Description: %s\n", nport
->p_descr
?nport
->p_descr
:"(null)");
179 printf(" MFS: %" PRIu16
"\n", nport
->p_mfs
);
180 printf(" TTL: %" PRIu16
"\n", nport
->p_ttl
);
182 printf(" Dot3 aggrID: %" PRIu32
"\n", nport
->p_aggregid
);
183 printf(" Dot3 MAC/phy autoneg supported: %" PRIu8
"\n", nport
->p_macphy
.autoneg_support
);
184 printf(" Dot3 MAC/phy autoneg enabled: %" PRIu8
"\n", nport
->p_macphy
.autoneg_enabled
);
185 printf(" Dot3 MAC/phy autoneg advertised: %" PRIu16
"\n", nport
->p_macphy
.autoneg_advertised
);
186 printf(" Dot3 MAC/phy MAU type: %" PRIu16
"\n", nport
->p_macphy
.mau_type
);
187 printf(" Dot3 power device type: %" PRIu8
"\n", nport
->p_power
.devicetype
);
188 printf(" Dot3 power supported: %" PRIu8
"\n", nport
->p_power
.supported
);
189 printf(" Dot3 power enabled: %" PRIu8
"\n", nport
->p_power
.enabled
);
190 printf(" Dot3 power pair control: %" PRIu8
"\n", nport
->p_power
.paircontrol
);
191 printf(" Dot3 power pairs: %" PRIu8
"\n", nport
->p_power
.pairs
);
192 printf(" Dot3 power class: %" PRIu8
"\n", nport
->p_power
.class);
193 printf(" Dot3 power type: %" PRIu8
"\n", nport
->p_power
.powertype
);
194 printf(" Dot3 power source: %" PRIu8
"\n", nport
->p_power
.source
);
195 printf(" Dot3 power priority: %" PRIu8
"\n", nport
->p_power
.priority
);
196 printf(" Dot3 power requested: %" PRIu16
"\n", nport
->p_power
.requested
);
197 printf(" Dot3 power allocated: %" PRIu16
"\n", nport
->p_power
.allocated
);
199 #ifdef ENABLE_LLDPMED
200 printf(" MED cap: %" PRIu16
"\n", nport
->p_med_cap_enabled
);
201 for (int i
= 0; i
< LLDP_MED_APPTYPE_LAST
; i
++) {
202 if (nport
->p_med_policy
[i
].type
== 0) continue;
203 printf(" MED policy type: %" PRIu8
"\n", nport
->p_med_policy
[i
].type
);
204 printf(" MED policy unknown: %" PRIu8
"\n", nport
->p_med_policy
[i
].unknown
);
205 printf(" MED policy tagged: %" PRIu8
"\n", nport
->p_med_policy
[i
].tagged
);
206 printf(" MED policy vid: %" PRIu16
"\n", nport
->p_med_policy
[i
].vid
);
207 printf(" MED policy priority: %" PRIu8
"\n", nport
->p_med_policy
[i
].priority
);
208 printf(" MED policy dscp: %" PRIu8
"\n", nport
->p_med_policy
[i
].dscp
);
210 for (int i
= 0; i
< LLDP_MED_LOCFORMAT_LAST
; i
++) {
211 if (nport
->p_med_location
[i
].format
== 0) continue;
212 printf(" MED location format: %" PRIu8
"\n", nport
->p_med_location
[i
].format
);
213 printf(" MED location: %s\n", tohex(nport
->p_med_location
[i
].data
,
214 nport
->p_med_location
[i
].data_len
));
216 printf(" MED power device type: %" PRIu8
"\n", nport
->p_med_power
.devicetype
);
217 printf(" MED power source: %" PRIu8
"\n", nport
->p_med_power
.source
);
218 printf(" MED power priority: %" PRIu8
"\n", nport
->p_med_power
.priority
);
219 printf(" MED power value: %" PRIu16
"\n", nport
->p_med_power
.val
);
222 printf(" Dot1 PVID: %" PRIu16
"\n", nport
->p_pvid
);
223 struct lldpd_vlan
*vlan
;
224 TAILQ_FOREACH(vlan
, &nport
->p_vlans
, v_entries
) {
225 printf(" Dot1 VLAN: %s (%" PRIu16
")\n", vlan
->v_name
, vlan
->v_vid
);
227 struct lldpd_ppvid
*ppvid
;
228 TAILQ_FOREACH(ppvid
, &nport
->p_ppvids
, p_entries
) {
229 printf(" Dot1 PPVID: %" PRIu16
" (status: %" PRIu8
")\n",
230 ppvid
->p_ppvid
, ppvid
->p_cap_status
);
232 struct lldpd_pi
*pid
;
233 TAILQ_FOREACH(pid
, &nport
->p_pids
, p_entries
) {
234 printf(" Dot1 PI: %s\n", tohex(pid
->p_pi
, pid
->p_pi_len
));
238 struct lldpd_custom
*custom
;
239 TAILQ_FOREACH(custom
, &nport
->p_custom_list
, next
) {
240 printf(" Custom OUI: %s\n",
241 tohex((char*)custom
->oui
, sizeof(custom
->oui
)));
242 printf(" Custom subtype: %" PRIu8
"\n", custom
->subtype
);
243 printf(" Custom info: %s\n",
244 tohex((char*)custom
->oui_info
, custom
->oui_info_len
));