Bug Summary

File:src/usr.sbin/tcpdump/print-nsh.c
Warning:line 180, column 2
Value stored to 'l' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name print-nsh.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -fno-rounding-math -mconstructor-aliases -munwind-tables -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/lib/clang/13.0.0 -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/lib/clang/13.0.0/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 -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/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/tcpdump/print-nsh.c
1/* $OpenBSD: print-nsh.c,v 1.1 2019/12/03 01:43:33 dlg Exp $ */
2
3/*
4 * Copyright (c) 2019 David Gwynne <dlg@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * RFC 8300 Network Service Header (NSH)
21 */
22
23#include <sys/time.h>
24#include <sys/uio.h>
25#include <sys/socket.h>
26
27#include <netinet/in.h>
28#include <netinet/ip.h>
29#include <arpa/inet.h>
30
31#include <stdio.h>
32#include <string.h>
33#include <ctype.h>
34
35#include "interface.h"
36#include "addrtoname.h"
37#include "extract.h"
38
39#ifndef roundup
40#define roundup(x, y)((((x)+((y)-1))/(y))*(y)) ((((x)+((y)-1))/(y))*(y))
41#endif
42
43#ifndef nitems
44#define nitems(_a)(sizeof((_a)) / sizeof((_a)[0])) (sizeof((_a)) / sizeof((_a)[0]))
45#endif
46
47struct nsh_header {
48 uint32_t base;
49#define NSH_VER_SHIFT30 30
50#define NSH_VER_MASK(0x03 << 30) (0x03 << NSH_VER_SHIFT30)
51#define NSH_VER_00x0 0x0
52#define NSH_VER_RESERVED(0x01 << 30) (0x01 << NSH_VER_SHIFT30)
53#define NSH_OAM_SHIFT29 29
54#define NSH_OAM_MASK(0x01 << 29) (0x01 << NSH_OAM_SHIFT29)
55#define NSH_TTL_SHIFT22 22
56#define NSH_TTL_MASK(0x3f << 22) (0x3f << NSH_TTL_SHIFT22)
57#define NSH_LEN_SHIFT16 16
58#define NSH_LEN_MASK(0x3f << 16) (0x3f << NSH_LEN_SHIFT16)
59#define NSH_LEN_FACTOR4 4
60#define NSH_MDTYPE_SHIFT8 8
61#define NSH_MDTYPE_MASK(0x0f << 8) (0x0f << NSH_MDTYPE_SHIFT8)
62#define NSH_PROTO_SHIFT0 0
63#define NSH_PROTO_MASK(0xff << 0) (0xff << NSH_PROTO_SHIFT0)
64
65 uint32_t sp;
66#define NSH_SPI_SHIFT8 8
67#define NSH_SPI_MASK(0xffffff << 8) (0xffffff << NSH_SPI_SHIFT8)
68#define NSH_SI_SHIFT0 0
69#define NSH_SI_MASK(0xff << 0) (0xff << NSH_SI_SHIFT0)
70};
71
72#define NSH_PROTO_IPV40x01 0x01
73#define NSH_PROTO_IPV60x02 0x02
74#define NSH_PROTO_ETHERNET0x03 0x03
75#define NSH_PROTO_NSH0x04 0x04
76#define NSH_PROTO_MPLS0x05 0x05
77#define NSH_PROTO_EXP10xfe 0xfe /* Experiment 1 */
78#define NSH_PROTO_EXP20xff 0xff /* Experiment 2 */
79
80#define NSH_MDTYPE_RESERVED0x0 0x0
81#define NSH_MDTYPE_10x1 0x1
82#define NSH_MDTYPE_20x2 0x2
83#define NSH_MDTYPE_EXP0xf 0xf /* Experimentation */
84
85struct nsh_context_header {
86 uint32_t ch[4];
87};
88
89struct nsh_md_header {
90 uint16_t class;
91 uint8_t type;
92 uint8_t len;
93#define NSH_MD_LEN_MASK0x7f 0x7f
94};
95
96static void nsh_print_bytes(const void *, u_int);
97
98static void nsh_print_mdtype1(const u_char *, u_int);
99static void nsh_print_mdtype2(const u_char *, u_int);
100
101void
102nsh_print(const u_char *p, u_int length)
103{
104 struct nsh_header nsh;
105 uint32_t field, len, proto;
106 int l = snapend - p;
107
108 printf("NSH");
109
110 if (l < sizeof(nsh))
111 goto trunc;
112 if (length < sizeof(nsh)) {
113 printf(" encapsulation truncated");
114 return;
115 }
116
117 nsh.base = EXTRACT_32BITS(p)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | (u_int32_t
)*((const u_int8_t *)(p) + 1) << 16 | (u_int32_t)*((const
u_int8_t *)(p) + 2) << 8 | (u_int32_t)*((const u_int8_t
*)(p) + 3))
;
118 nsh.sp = EXTRACT_32BITS(p + sizeof(nsh.base))((u_int32_t)*((const u_int8_t *)(p + sizeof(nsh.base)) + 0) <<
24 | (u_int32_t)*((const u_int8_t *)(p + sizeof(nsh.base)) +
1) << 16 | (u_int32_t)*((const u_int8_t *)(p + sizeof(
nsh.base)) + 2) << 8 | (u_int32_t)*((const u_int8_t *)(
p + sizeof(nsh.base)) + 3))
;
119
120 field = (nsh.base & NSH_VER_MASK(0x03 << 30)) >> NSH_VER_SHIFT30;
121 switch (field) {
122 case NSH_VER_00x0:
123 break;
124 case NSH_VER_RESERVED(0x01 << 30):
125 printf(" Reserved version");
126 return;
127 default:
128 printf(" Unknown version %u", field);
129 return;
130 }
131
132 field = (nsh.sp & NSH_SPI_MASK(0xffffff << 8)) >> NSH_SPI_SHIFT8;
133 printf(" spi %u", field);
134 field = (nsh.sp & NSH_SI_MASK(0xff << 0)) >> NSH_SI_SHIFT0;
135 printf(" si %u", field);
136
137 len = ((nsh.base & NSH_LEN_MASK(0x3f << 16)) >> NSH_LEN_SHIFT16) * NSH_LEN_FACTOR4;
138 if (vflag > 1) {
139 field = (nsh.base & NSH_TTL_MASK(0x3f << 22)) >> NSH_TTL_SHIFT22;
140 printf(" (ttl %u, len %u)", field, len);
141 }
142
143 if (l < len)
144 goto trunc;
145 if (length < len) {
146 printf(" encapsulation truncated");
147 return;
148 }
149
150 p += sizeof(nsh);
151 l -= sizeof(nsh);
152 len -= sizeof(nsh);
153
154 field = (nsh.base & NSH_MDTYPE_MASK(0x0f << 8)) >> NSH_MDTYPE_SHIFT8;
155 switch (field) {
156 case NSH_MDTYPE_RESERVED0x0:
157 printf(" md-type-reserved");
158 break;
159 case NSH_MDTYPE_10x1:
160 printf(" md1");
161 if (vflag)
162 nsh_print_mdtype1(p, len);
163 break;
164 case NSH_MDTYPE_20x2:
165 printf(" md2");
166 if (vflag)
167 nsh_print_mdtype2(p, len);
168 break;
169 case NSH_MDTYPE_EXP0xf:
170 printf(" mdtype-experimentation");
171 break;
172 default:
173 printf(" mdtype-unknown-0x%02x", field);
174 break;
175 }
176
177 printf("%s", vflag ? "\n " : ": ");
178
179 p += len;
180 l -= len;
Value stored to 'l' is never read
181 length -= len;
182
183 proto = (nsh.base & NSH_PROTO_MASK(0xff << 0)) >> NSH_PROTO_SHIFT0;
184
185 if (nsh.base & NSH_OAM_MASK(0x01 << 29))
186 printf("NSH OAM (proto 0x%0x, len %u)", proto, length);
187 else {
188 switch (field) {
189 case NSH_PROTO_IPV40x01:
190 ip_print(p, length);
191 return;
192 case NSH_PROTO_IPV60x02:
193 ip_print(p, length);
194 return;
195 case NSH_PROTO_ETHERNET0x03:
196 ether_tryprint(p, length, 0);
197 return;
198 case NSH_PROTO_NSH0x04:
199 nsh_print(p, length);
200 return;
201 case NSH_PROTO_MPLS0x05:
202 mpls_print(p, length);
203 return;
204 case NSH_PROTO_EXP10xfe:
205 printf("NSH Experiment 1");
206 break;
207 case NSH_PROTO_EXP20xff:
208 printf("NSH Experiment 2");
209 break;
210 default:
211 printf("nsh-unknown-proto-0x%02x", field);
212 break;
213 }
214 }
215
216 if (vflag)
217 default_print_unaligned(p, length);
218
219 return;
220trunc:
221 printf(" [|nsh]");
222}
223
224static void
225nsh_print_mdtype1(const u_char *p, u_int len)
226{
227 const struct nsh_context_header *ctx;
228 size_t i;
229
230 if (len != sizeof(*ctx))
231 printf("nsh-mdtype1-length-%u (not %zu)", len, sizeof(*ctx));
232
233 printf("\n\tcontext");
234
235 ctx = (const struct nsh_context_header *)p;
236 for (i = 0; i < nitems(ctx->ch)(sizeof((ctx->ch)) / sizeof((ctx->ch)[0])); i++) {
237 printf(" ");
238 nsh_print_bytes(&ctx->ch[i], sizeof(ctx->ch[i]));
239 }
240}
241
242static void
243nsh_print_mdtype2(const u_char *p, u_int l)
244{
245 if (l == 0)
246 return;
247
248 do {
249 struct nsh_md_header h;
250 uint8_t len;
251
252 if (l < sizeof(h))
253 goto trunc;
254
255 memcpy(&h, p, sizeof(h));
256 p += sizeof(h);
257 l -= sizeof(h);
258
259 h.class = ntohs(h.class)(__uint16_t)(__builtin_constant_p(h.class) ? (__uint16_t)(((__uint16_t
)(h.class) & 0xffU) << 8 | ((__uint16_t)(h.class) &
0xff00U) >> 8) : __swap16md(h.class))
;
260 len = h.len & NSH_MD_LEN_MASK0x7f;
261 printf("\n\tmd class %u type %u", h.class, h.type);
262 if (len > 0) {
263 printf(" ");
264 nsh_print_bytes(p, len);
265 }
266
267 len = roundup(len, 4)((((len)+((4)-1))/(4))*(4));
268 if (l < len)
269 goto trunc;
270
271 p += len;
272 l -= len;
273 } while (l > 0);
274
275 return;
276trunc:
277 printf("[|nsh md]");
278}
279
280static void
281nsh_print_bytes(const void *b, u_int l)
282{
283 const uint8_t *p = b;
284 u_int i;
285
286 for (i = 0; i < l; i++) {
287 int ch = p[i];
288#if 0
289 if (isprint(ch) && !isspace(ch))
290 putchar(ch)(!__isthreaded ? __sputc(ch, (&__sF[1])) : (putc)(ch, (&
__sF[1])))
;
291 else {
292 switch (ch) {
293 case '\\':
294 printf("\\\\");
295 break;
296 case '\0':
297 printf("\\0");
298 break;
299 default:
300 printf("\\x%02x", ch);
301 break;
302 }
303 }
304#else
305 printf("%02x", ch);
306#endif
307 }
308}