Bug Summary

File:src/usr.sbin/tcpdump/print-ether.c
Warning:line 183, column 2
Value stored to 'caplen' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name print-ether.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/tcpdump/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/usr.sbin/tcpdump/../../sbin/pfctl -I /usr/src/usr.sbin/tcpdump/../hostapd -I /usr/src/usr.sbin/tcpdump/../../lib/libpcap -D CSLIP -D PPP -D HAVE_FDDI -D ETHER_SERVICE -D HAVE_ETHER_NTOHOST -D INET6 -I /usr/src/usr.sbin/tcpdump/../../sbin/pfctl -D FAKE_PF_KERNEL -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/tcpdump/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/tcpdump/print-ether.c
1/* $OpenBSD: print-ether.c,v 1.42 2022/06/09 12:56:14 mbuhl Exp $ */
2
3/*
4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24#include <sys/time.h>
25#include <sys/socket.h>
26
27#include <net/if.h>
28
29#include <netinet/in.h>
30#include <netinet/if_ether.h>
31#include <netinet/ip.h>
32#include <netinet/ip6.h>
33#include <netinet/ip_var.h>
34#include <netinet/udp.h>
35#include <netinet/udp_var.h>
36#include <netinet/tcp.h>
37
38#include <stdio.h>
39#include <stddef.h>
40#include <pcap.h>
41
42
43#include "interface.h"
44#include "addrtoname.h"
45#include "ethertype.h"
46#include "extract.h"
47
48const u_char *packetp;
49const u_char *snapend;
50
51void ether_macctl(const u_char *, u_int);
52void ether_pbb_print(const u_char *, u_int, u_int);
53void ether_eapol_print(const u_char *, u_int, u_int);
54
55void
56ether_print(const u_char *bp, u_int length)
57{
58 const struct ether_header *ep;
59
60 ep = (const struct ether_header *)bp;
61 if (qflag) {
62 TCHECK2(*ep, 12)if (!(snapend - (12) <= snapend && (const u_char *
)&(*ep) <= snapend - (12))) goto trunc
;
63 printf("%s %s %d: ",
64 etheraddr_string(ESRC(ep)((ep)->ether_shost)),
65 etheraddr_string(EDST(ep)((ep)->ether_dhost)),
66 length);
67 } else {
68 TCHECK2(*ep, 14)if (!(snapend - (14) <= snapend && (const u_char *
)&(*ep) <= snapend - (14))) goto trunc
;
69 printf("%s %s %s %d: ",
70 etheraddr_string(ESRC(ep)((ep)->ether_shost)),
71 etheraddr_string(EDST(ep)((ep)->ether_dhost)),
72 etherproto_string(ep->ether_type),
73 length);
74 }
75 return;
76trunc:
77 printf("[|ether] ");
78}
79
80u_short extracted_ethertype;
81
82/*
83 * This is the top level routine of the printer. 'p' is the points
84 * to the ether header of the packet, 'tvp' is the timestamp,
85 * 'length' is the length of the packet off the wire, and 'caplen'
86 * is the number of bytes actually captured.
87 */
88void
89ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
90{
91 ts_print(&h->ts);
92
93 /*
94 * Some printers want to get back at the ethernet addresses,
95 * and/or check that they're not walking off the end of the packet.
96 * Rather than pass them all the way down, we set these globals.
97 */
98 snapend = p + h->caplen;
99
100 ether_tryprint(p, h->len, 1);
101}
102
103void
104ether_tryprint(const u_char *p, u_int length, int first_header)
105{
106 struct ether_header *ep;
107 u_int caplen = snapend - p;
108 u_short ether_type;
109
110 if (caplen < sizeof(struct ether_header)) {
111 printf("[|ether]");
112 goto out;
113 }
114
115 if (eflag)
116 ether_print(p, length);
117
118 packetp = p;
119 length -= sizeof(struct ether_header);
120 caplen -= sizeof(struct ether_header);
121 ep = (struct ether_header *)p;
122 p += sizeof(struct ether_header);
123
124 ether_type = ntohs(ep->ether_type)(__uint16_t)(__builtin_constant_p(ep->ether_type) ? (__uint16_t
)(((__uint16_t)(ep->ether_type) & 0xffU) << 8 | (
(__uint16_t)(ep->ether_type) & 0xff00U) >> 8) : __swap16md
(ep->ether_type))
;
125
126 /*
127 * Is it (gag) an 802.3 encapsulation?
128 */
129 extracted_ethertype = 0;
130 if (ether_type <= ETHERMTU(1518 - ((6 * 2) + 2) - 4)) {
131 /* Try to print the LLC-layer header & higher layers */
132 if (llc_print(p, length, caplen, ESRC(ep)((ep)->ether_shost), EDST(ep)((ep)->ether_dhost)) == 0) {
133 /* ether_type not known, print raw packet */
134 if (!eflag)
135 ether_print((u_char *)ep, length);
136 if (extracted_ethertype) {
137 printf("(LLC %s) ",
138 etherproto_string(htons(extracted_ethertype)(__uint16_t)(__builtin_constant_p(extracted_ethertype) ? (__uint16_t
)(((__uint16_t)(extracted_ethertype) & 0xffU) << 8 |
((__uint16_t)(extracted_ethertype) & 0xff00U) >> 8
) : __swap16md(extracted_ethertype))
));
139 }
140 if (!xflag && !qflag) {
141 if (eflag)
142 default_print(packetp,
143 snapend - packetp);
144 else
145 default_print(p, caplen);
146 }
147 }
148 } else if (ether_encap_print(ether_type, p, length, caplen) == 0) {
149 /* ether_type not known, print raw packet */
150 if (!eflag)
151 ether_print((u_char *)ep, length + sizeof(*ep));
152 if (!xflag && !qflag) {
153 if (eflag)
154 default_print(packetp, snapend - packetp);
155 else
156 default_print(p, caplen);
157 }
158 }
159 if (xflag && first_header) {
160 if (eflag)
161 default_print(packetp, snapend - packetp);
162 else
163 default_print(p, caplen);
164 }
165 out:
166 if (first_header)
167 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
168}
169
170void
171ether_pbb_print(const u_char *bp, u_int length, u_int caplen)
172{
173 uint32_t itag;
174 uint8_t pri, res;
175
176 if (caplen < sizeof(itag))
177 goto trunc;
178
179 itag = EXTRACT_32BITS(bp)((u_int32_t)*((const u_int8_t *)(bp) + 0) << 24 | (u_int32_t
)*((const u_int8_t *)(bp) + 1) << 16 | (u_int32_t)*((const
u_int8_t *)(bp) + 2) << 8 | (u_int32_t)*((const u_int8_t
*)(bp) + 3))
;
180
181 bp += sizeof(itag);
182 length -= sizeof(itag);
183 caplen -= sizeof(itag);
Value stored to 'caplen' is never read
184
185 pri = itag >> 29;
186 if (pri <= 1)
187 pri = !pri;
188
189 res = (itag >> 24) & 0x7;
190
191 printf("802.1Q ivid %u pri %u ", itag & 0xffffff, pri);
192 if (itag & (1 << 28))
193 printf("dei ");
194 if (itag & (1 << 27))
195 printf("uca ");
196 if (res)
197 printf("res %u! ", res);
198
199 ether_tryprint(bp, length, 0);
200
201 return;
202
203trunc:
204 printf("[|pbb] ");
205}
206
207/*
208 * Prints the packet encapsulated in an Ethernet data segment
209 * (or an equivalent encapsulation), given the Ethernet type code.
210 *
211 * Returns non-zero if it can do so, zero if the ethertype is unknown.
212 *
213 * Stuffs the ether type into a global for the benefit of lower layers
214 * that might want to know what it is.
215 */
216
217int
218ether_encap_print(u_short ethertype, const u_char *p,
219 u_int length, u_int caplen)
220{
221 uint16_t vlan, pri, vid;
222recurse:
223 extracted_ethertype = ethertype;
224
225 switch (ethertype) {
226
227 case ETHERTYPE_IP0x0800:
228 ip_print(p, length);
229 return (1);
230
231 case ETHERTYPE_IPV60x86DD:
232 ip6_print(p, length);
233 return (1);
234
235 case ETHERTYPE_ARP0x0806:
236 case ETHERTYPE_REVARP0x8035:
237 arp_print(p, length, caplen);
238 return (1);
239
240 case ETHERTYPE_DN0x6003:
241 decnet_print(p, length, caplen);
242 return (1);
243
244 case ETHERTYPE_ATALK0x809B:
245 if (vflag)
246 printf("et1 ");
247 atalk_print_llap(p, length);
248 return (1);
249
250 case ETHERTYPE_AARP0x80F3:
251 aarp_print(p, length);
252 return (1);
253
254 case ETHERTYPE_8021Q0x8100:
255 printf("802.1Q ");
256 case ETHERTYPE_QINQ0x88A8:
257 if (ethertype == ETHERTYPE_QINQ0x88A8)
258 printf("QinQ s");
259
260 /* XXX caplen check */
261
262 vlan = ntohs(*(unsigned short*)p)(__uint16_t)(__builtin_constant_p(*(unsigned short*)p) ? (__uint16_t
)(((__uint16_t)(*(unsigned short*)p) & 0xffU) << 8 |
((__uint16_t)(*(unsigned short*)p) & 0xff00U) >> 8
) : __swap16md(*(unsigned short*)p))
;
263 vid = vlan & 0xfff;
264 pri = vlan >> 13;
265 if (pri <= 1)
266 pri = !pri;
267
268 printf("vid %d pri %d%s", vid, pri,
269 vlan & 0x1000 ? " dei " : " ");
270 ethertype = ntohs(*(unsigned short*)(p+2))(__uint16_t)(__builtin_constant_p(*(unsigned short*)(p+2)) ? (
__uint16_t)(((__uint16_t)(*(unsigned short*)(p+2)) & 0xffU
) << 8 | ((__uint16_t)(*(unsigned short*)(p+2)) & 0xff00U
) >> 8) : __swap16md(*(unsigned short*)(p+2)))
;
271 p += 4;
272 length -= 4;
273 caplen -= 4;
274 if (ethertype > ETHERMTU(1518 - ((6 * 2) + 2) - 4))
275 goto recurse;
276
277 extracted_ethertype = 0;
278
279 if (llc_print(p, length, caplen, p-18, p-12) == 0) {
280 /* ether_type not known, print raw packet */
281 if (!eflag)
282 ether_print(p-18, length+4);
283 if (extracted_ethertype) {
284 printf("(LLC %s) ",
285 etherproto_string(htons(extracted_ethertype)(__uint16_t)(__builtin_constant_p(extracted_ethertype) ? (__uint16_t
)(((__uint16_t)(extracted_ethertype) & 0xffU) << 8 |
((__uint16_t)(extracted_ethertype) & 0xff00U) >> 8
) : __swap16md(extracted_ethertype))
));
286 }
287 if (!xflag && !qflag)
288 default_print(p-18, caplen+4);
289 }
290 return (1);
291
292 case ETHERTYPE_NSH0x894F:
293 nsh_print(p, length);
294 return (1);
295
296 case ETHERTYPE_EAPOL0x888E:
297 ether_eapol_print(p, length, caplen);
298 return (1);
299
300 case ETHERTYPE_PBB0x88e7:
301 ether_pbb_print(p, length, caplen);
302 return (1);
303
304 case ETHERTYPE_NHRP0x2001:
305 nhrp_print(p, length);
306 return (1);
307
308#ifdef PPP1
309 case ETHERTYPE_PPPOEDISC0x8863:
310 case ETHERTYPE_PPPOE0x8864:
311 pppoe_if_print(ethertype, p, length, caplen);
312 return (1);
313#endif
314
315 case ETHERTYPE_FLOWCONTROL0x8808:
316 ether_macctl(p, length);
317 return (1);
318
319 case ETHERTYPE_MPLS0x8847:
320 case ETHERTYPE_MPLS_MCAST0x8848:
321 mpls_print(p, length);
322 return (1);
323
324 case ETHERTYPE_LLDP0x88CC:
325 lldp_print(p, length);
326 return (1);
327
328 case ETHERTYPE_SLOW0x8809:
329 slow_print(p, length);
330 return (1);
331
332 case ETHERTYPE_LAT0x6004:
333 case ETHERTYPE_SCA0x6007:
334 case ETHERTYPE_MOPRC0x6002:
335 case ETHERTYPE_MOPDL0x6001:
336 /* default_print for now */
337 default:
338 return (0);
339 }
340}
341
342void
343ether_macctl(const u_char *p, u_int length)
344{
345 printf("MACCTL");
346
347 if (length < 2)
348 goto trunc;
349 if (EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
== 0x0001) {
350 u_int plen;
351
352 printf(" PAUSE");
353
354 length -= 2;
355 p += 2;
356 if (length < 2)
357 goto trunc;
358 plen = 512 * EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
359 printf(" quanta %u", plen);
360 } else {
361 printf(" unknown-opcode(0x%04x)", EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
);
362 }
363 return;
364
365trunc:
366 printf("[|MACCTL]");
367}
368
369/*
370 * 802.1X EAPOL PDU
371 */
372
373struct eapol_header {
374 uint8_t version;
375 uint8_t type;
376#define EAPOL_T_EAP0x00 0x00
377#define EAPOL_T_START0x01 0x01
378#define EAPOL_T_LOGOFF0x02 0x02
379#define EAPOL_T_KEY0x03 0x03
380#define EAPOL_T_ENCAP_ASF_ALERT0x04 0x04
381#define EAPOL_T_MKA0x05 0x05
382#define EAPOL_T_ANNOUNCEMENT_GENERIC0x06 0x06
383#define EAPOL_T_ANNOUNCEMENT_SPECIFIC0x07 0x07
384#define EAPOL_T_ANNOUNCEMENT_REQ0x08 0x08
385 uint16_t length;
386};
387
388void
389ether_eapol_print(const u_char *bp, u_int length, u_int caplen)
390{
391 struct eapol_header h;
392
393 printf("EAPOL");
394
395 if (caplen < sizeof(h))
396 goto trunc;
397
398 h.version = *(bp + offsetof(struct eapol_header, version)__builtin_offsetof(struct eapol_header, version));
399 h.type = *(bp + offsetof(struct eapol_header, type)__builtin_offsetof(struct eapol_header, type));
400 h.length = EXTRACT_16BITS(bp + offsetof(struct eapol_header, length))((u_int16_t)*((const u_int8_t *)(bp + __builtin_offsetof(struct
eapol_header, length)) + 0) << 8 | (u_int16_t)*((const
u_int8_t *)(bp + __builtin_offsetof(struct eapol_header, length
)) + 1))
;
401
402 bp += sizeof(h);
403 length -= sizeof(h);
404 caplen -= sizeof(h);
405
406 if (vflag)
407 printf(" (v%u, len %u)", h.version, h.length);
408
409 if (length > h.length)
410 length = h.length;
411 else if (length < h.length) {
412 printf(" truncated-eapol - %u bytes missing!",
413 h.length - length);
414 }
415
416 switch (h.type) {
417 case EAPOL_T_EAP0x00:
418 printf(" EAP");
419 break;
420 case EAPOL_T_START0x01:
421 printf(" Start");
422 break;
423 case EAPOL_T_LOGOFF0x02:
424 printf(" Logoff");
425 break;
426 case EAPOL_T_KEY0x03:
427 printf(" Key");
428 break;
429 case EAPOL_T_MKA0x05:
430 printf(" MKA");
431 break;
432 case EAPOL_T_ANNOUNCEMENT_GENERIC0x06:
433 printf(" Announcement (Generic)");
434 break;
435 case EAPOL_T_ANNOUNCEMENT_SPECIFIC0x07:
436 printf(" Announcement (Specific)");
437 break;
438 case EAPOL_T_ANNOUNCEMENT_REQ0x08:
439 printf(" Announcement Req");
440 break;
441 default:
442 printf(" unknown (%u)", h.type);
443 break;
444 }
445
446 return;
447
448trunc:
449 printf(" [|eapol] ");
450}