clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.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.bin/netstat/obj -resource-dir /usr/local/llvm16/lib/clang/16 -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/netstat/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.bin/netstat/main.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | #include <sys/types.h> |
34 | #include <sys/protosw.h> |
35 | #include <sys/socket.h> |
36 | #include <sys/sysctl.h> |
37 | |
38 | #include <net/route.h> |
39 | #include <netinet/in.h> |
40 | |
41 | #include <ctype.h> |
42 | #include <err.h> |
43 | #include <errno.h> |
44 | #include <fcntl.h> |
45 | #include <kvm.h> |
46 | #include <limits.h> |
47 | #include <netdb.h> |
48 | #include <nlist.h> |
49 | #include <paths.h> |
50 | #include <stdio.h> |
51 | #include <stdlib.h> |
52 | #include <string.h> |
53 | #include <unistd.h> |
54 | #include "netstat.h" |
55 | |
56 | struct nlist nl[] = { |
57 | #define N_AFMAP 0 |
58 | { "_afmap"}, |
59 | #define N_AF2IDX 1 |
60 | { "_af2idx" }, |
61 | #define N_AF2IDXMAX 2 |
62 | { "_af2idx_max" }, |
63 | |
64 | { "" } |
65 | }; |
66 | |
67 | struct protox { |
68 | void (*pr_stats)(char *); |
69 | char *pr_name; |
70 | int pr_proto; |
71 | } protox[] = { |
72 | { ip_stats, "ip", IPPROTO_IPV4 }, |
73 | { icmp_stats, "icmp", 0 }, |
74 | { igmp_stats, "igmp", 0 }, |
75 | { ipip_stats, "ipencap", 0 }, |
76 | { tcp_stats, "tcp", IPPROTO_TCP }, |
77 | { udp_stats, "udp", IPPROTO_UDP }, |
78 | { ipsec_stats, "ipsec", 0 }, |
79 | { esp_stats, "esp", 0 }, |
80 | { ah_stats, "ah", 0 }, |
81 | { etherip_stats,"etherip", 0 }, |
82 | { ipcomp_stats, "ipcomp", 0 }, |
83 | { carp_stats, "carp", 0 }, |
84 | { pfsync_stats, "pfsync", 0 }, |
85 | { div_stats, "divert", IPPROTO_DIVERT }, |
86 | { pflow_stats, "pflow", 0 }, |
87 | { NULL, NULL, 0 } |
88 | }; |
89 | |
90 | struct protox ip6protox[] = { |
91 | { ip6_stats, "ip6", IPPROTO_IPV6 }, |
92 | { div6_stats, "divert6", IPPROTO_DIVERT }, |
93 | { icmp6_stats, "icmp6", 0 }, |
94 | { rip6_stats, "rip6", 0 }, |
95 | { NULL, NULL, 0 } |
96 | }; |
97 | |
98 | struct protox *protoprotox[] = { |
99 | protox, ip6protox, NULL |
100 | }; |
101 | |
102 | static void usage(void); |
103 | static struct protox *name2protox(char *); |
104 | static struct protox *knownname(char *); |
105 | void gettable(u_int); |
106 | |
107 | kvm_t *kvmd; |
108 | |
109 | int Aflag; |
110 | int aflag; |
111 | int Bflag; |
112 | int bflag; |
113 | int dflag; |
114 | int Fflag; |
115 | int gflag; |
116 | int hflag; |
117 | int iflag; |
118 | int lflag; |
119 | |
120 | int mflag; |
121 | int nflag; |
122 | int pflag; |
123 | int Pflag; |
124 | int qflag; |
125 | int rflag; |
126 | int Rflag; |
127 | int sflag; |
128 | int vflag; |
129 | int Wflag; |
130 | |
131 | int interval; |
132 | |
133 | char *interface; |
134 | |
135 | int af; |
136 | |
137 | int |
138 | main(int argc, char *argv[]) |
139 | { |
140 | extern char *optarg; |
141 | extern int optind; |
142 | const char *errstr; |
143 | struct protox *tp = NULL; |
| 1 | 'tp' initialized to a null pointer value | |
|
144 | int ch; |
145 | char *nlistf = NULL, *memf = NULL, *ep; |
146 | char buf[_POSIX2_LINE_MAX]; |
147 | u_long pcbaddr = 0; |
148 | u_int tableid; |
149 | int Tflag = 0; |
150 | int repeatcount = 0; |
151 | int proto = 0; |
152 | int need_nlist, kvm_flags = O_RDONLY; |
153 | |
154 | af = AF_UNSPEC; |
155 | tableid = getrtable(); |
156 | |
157 | while ((ch = getopt(argc, argv, |
| 2 | | Assuming the condition is false | |
|
| 3 | | Loop condition is false. Execution continues on line 290 | |
|
158 | "AaBbc:deFf:ghI:iLlM:mN:np:P:qRrsT:uvW:w:")) != -1) |
159 | switch (ch) { |
160 | case 'A': |
161 | Aflag = 1; |
162 | break; |
163 | case 'a': |
164 | aflag = 1; |
165 | break; |
166 | case 'B': |
167 | Bflag = 1; |
168 | break; |
169 | case 'b': |
170 | bflag = 1; |
171 | break; |
172 | case 'c': |
173 | repeatcount = strtonum(optarg, 1, INT_MAX, &errstr); |
174 | if (errstr) |
175 | errx(1, "count is %s", errstr); |
176 | break; |
177 | case 'd': |
178 | dflag = IF_SHOW_DROP; |
179 | break; |
180 | case 'e': |
181 | dflag = IF_SHOW_ERRS; |
182 | break; |
183 | case 'F': |
184 | Fflag = 1; |
185 | break; |
186 | case 'f': |
187 | if (strcmp(optarg, "inet") == 0) |
188 | af = AF_INET; |
189 | else if (strcmp(optarg, "inet6") == 0) |
190 | af = AF_INET6; |
191 | else if (strcmp(optarg, "local") == 0) |
192 | af = AF_LOCAL; |
193 | else if (strcmp(optarg, "unix") == 0) |
194 | af = AF_UNIX; |
195 | else if (strcmp(optarg, "mpls") == 0) |
196 | af = AF_MPLS; |
197 | else { |
198 | (void)fprintf(stderr, |
199 | "%s: %s: unknown address family\n", |
200 | __progname, optarg); |
201 | exit(1); |
202 | } |
203 | break; |
204 | case 'g': |
205 | gflag = 1; |
206 | break; |
207 | case 'h': |
208 | hflag = 1; |
209 | break; |
210 | case 'I': |
211 | iflag = 1; |
212 | interface = optarg; |
213 | break; |
214 | case 'i': |
215 | iflag = 1; |
216 | break; |
217 | case 'l': |
218 | lflag = 1; |
219 | break; |
220 | case 'M': |
221 | memf = optarg; |
222 | break; |
223 | case 'm': |
224 | mflag = 1; |
225 | break; |
226 | case 'N': |
227 | nlistf = optarg; |
228 | break; |
229 | case 'n': |
230 | nflag = 1; |
231 | break; |
232 | case 'p': |
233 | if ((tp = name2protox(optarg)) == NULL) { |
234 | (void)fprintf(stderr, |
235 | "%s: %s: unknown protocol\n", |
236 | __progname, optarg); |
237 | exit(1); |
238 | } |
239 | pflag = 1; |
240 | break; |
241 | case 'P': |
242 | errno = 0; |
243 | pcbaddr = strtoul(optarg, &ep, 16); |
244 | if (optarg[0] == '\0' || *ep != '\0' || |
245 | errno == ERANGE) { |
246 | (void)fprintf(stderr, |
247 | "%s: %s: invalid PCB address\n", |
248 | __progname, optarg); |
249 | exit(1); |
250 | } |
251 | Pflag = 1; |
252 | break; |
253 | case 'q': |
254 | qflag = 1; |
255 | break; |
256 | case 'R': |
257 | Rflag = 1; |
258 | break; |
259 | case 'r': |
260 | rflag = 1; |
261 | break; |
262 | case 's': |
263 | ++sflag; |
264 | break; |
265 | case 'T': |
266 | tableid = strtonum(optarg, 0, RT_TABLEID_MAX, &errstr); |
267 | if (errstr) |
268 | errx(1, "invalid table id: %s", errstr); |
269 | Tflag = 1; |
270 | break; |
271 | case 'u': |
272 | af = AF_UNIX; |
273 | break; |
274 | case 'v': |
275 | vflag = 1; |
276 | break; |
277 | case 'W': |
278 | Wflag = 1; |
279 | interface = optarg; |
280 | break; |
281 | case 'w': |
282 | interval = strtonum(optarg, 1, INT_MAX, &errstr); |
283 | if (errstr) |
284 | errx(1, "interval is %s", errstr); |
285 | iflag = 1; |
286 | break; |
287 | default: |
288 | usage(); |
289 | } |
290 | argv += optind; |
291 | argc -= optind; |
292 | |
293 | if (argc) { |
| |
| |
294 | interval = strtonum(*argv, 1, INT_MAX, &errstr); |
295 | if (errstr) |
296 | errx(1, "interval is %s", errstr); |
297 | ++argv; |
298 | --argc; |
299 | iflag = 1; |
300 | } |
301 | if (argc) |
| |
302 | usage(); |
303 | |
304 | |
305 | |
306 | |
307 | |
308 | if (Wflag) { |
| |
| |
309 | if (interface == NULL) |
310 | usage(); |
311 | net80211_ifstats(interface); |
312 | exit(0); |
313 | } |
314 | |
315 | if (mflag) { |
| |
| |
316 | mbpr(); |
317 | exit(0); |
318 | } |
319 | if (iflag) { |
| |
| |
320 | intpr(interval, repeatcount); |
321 | exit(0); |
322 | } |
323 | if (sflag) { |
| |
| |
324 | if (rflag) { |
325 | rt_stats(); |
326 | } else if (gflag) { |
327 | if (af == AF_INET || af == AF_UNSPEC) |
328 | mrt_stats(); |
329 | if (af == AF_INET6 || af == AF_UNSPEC) |
330 | mrt6_stats(); |
331 | } else if (pflag && tp->pr_name) { |
332 | (*tp->pr_stats)(tp->pr_name); |
333 | } else { |
334 | if (af == AF_INET || af == AF_UNSPEC) |
335 | for (tp = protox; tp->pr_name; tp++) |
336 | (*tp->pr_stats)(tp->pr_name); |
337 | if (af == AF_INET6 || af == AF_UNSPEC) |
338 | for (tp = ip6protox; tp->pr_name; tp++) |
339 | (*tp->pr_stats)(tp->pr_name); |
340 | } |
341 | exit(0); |
342 | } |
343 | if (gflag) { |
| |
| |
344 | if (af == AF_INET || af == AF_UNSPEC) |
345 | mroutepr(); |
346 | if (af == AF_INET6 || af == AF_UNSPEC) |
347 | mroute6pr(); |
348 | exit(0); |
349 | } |
350 | |
351 | if (Rflag) { |
| |
352 | rdomainpr(); |
353 | exit(0); |
354 | } |
355 | |
356 | |
357 | |
358 | |
359 | |
360 | need_nlist = (nlistf != NULL) || (memf != NULL) || (Aflag && rflag); |
| |
361 | if (!need_nlist && !Pflag) |
| 19 | | Assuming 'Pflag' is not equal to 0 | |
|
| |
362 | kvm_flags |= KVM_NO_FILES; |
363 | |
364 | if ((kvmd = kvm_openfiles(nlistf, memf, NULL, kvm_flags, buf)) == NULL) |
| 21 | | Assuming the condition is false | |
|
365 | errx(1, "kvm_openfiles: %s", buf); |
366 | |
367 | if (need_nlist && (kvm_nlist(kvmd, nl) < 0 || nl[0].n_type == 0)) { |
368 | if (nlistf) |
369 | errx(1, "%s: no namelist", nlistf); |
370 | else |
371 | errx(1, "no namelist"); |
372 | } |
373 | |
374 | if (!need_nlist && Tflag) |
| |
375 | gettable(tableid); |
376 | |
377 | if (rflag) { |
| |
| |
378 | if (Aflag || nlistf != NULL || memf != NULL) |
379 | routepr(nl[N_AFMAP].n_value, nl[N_AF2IDX].n_value, |
380 | nl[N_AF2IDXMAX].n_value, tableid); |
381 | else |
382 | p_rttables(af, tableid); |
383 | exit(0); |
384 | } |
385 | |
386 | if (pflag) { |
| 25 | | Assuming 'pflag' is not equal to 0 | |
|
| |
387 | if (tp->pr_proto == 0) |
| 27 | | Access to field 'pr_proto' results in a dereference of a null pointer (loaded from variable 'tp') |
|
388 | errx(1, "no protocol handler for protocol %s", |
389 | tp->pr_name); |
390 | else |
391 | proto = tp->pr_proto; |
392 | } |
393 | |
394 | protopr(kvmd, pcbaddr, tableid, proto); |
395 | exit(0); |
396 | } |
397 | |
398 | |
399 | |
400 | |
401 | int |
402 | kread(u_long addr, void *buf, int size) |
403 | { |
404 | |
405 | if (kvm_read(kvmd, addr, buf, size) != size) { |
406 | (void)fprintf(stderr, "%s: %s\n", __progname, |
407 | kvm_geterr(kvmd)); |
408 | return (-1); |
409 | } |
410 | return (0); |
411 | } |
412 | |
413 | char * |
414 | plural(u_int64_t n) |
415 | { |
416 | return (n != 1 ? "s" : ""); |
417 | } |
418 | |
419 | char * |
420 | plurales(u_int64_t n) |
421 | { |
422 | return (n != 1 ? "es" : ""); |
423 | } |
424 | |
425 | char * |
426 | pluralys(u_int64_t n) |
427 | { |
428 | return (n != 1 ? "ies" : "y"); |
429 | } |
430 | |
431 | |
432 | |
433 | |
434 | static struct protox * |
435 | knownname(char *name) |
436 | { |
437 | struct protox **tpp, *tp; |
438 | |
439 | for (tpp = protoprotox; *tpp; tpp++) |
440 | for (tp = *tpp; tp->pr_name; tp++) |
441 | if (strcmp(tp->pr_name, name) == 0) |
442 | return (tp); |
443 | return (NULL); |
444 | } |
445 | |
446 | |
447 | |
448 | |
449 | static struct protox * |
450 | name2protox(char *name) |
451 | { |
452 | struct protox *tp; |
453 | char **alias; |
454 | struct protoent *p; |
455 | |
456 | |
457 | |
458 | |
459 | |
460 | if ((tp = knownname(name))) |
461 | return (tp); |
462 | |
463 | setprotoent(1); |
464 | while ((p = getprotoent())) { |
465 | |
466 | for (alias = p->p_aliases; *alias; alias++) |
467 | if (strcmp(name, *alias) == 0) { |
468 | endprotoent(); |
469 | return (knownname(p->p_name)); |
470 | } |
471 | } |
472 | endprotoent(); |
473 | return (NULL); |
474 | } |
475 | |
476 | static void |
477 | usage(void) |
478 | { |
479 | (void)fprintf(stderr, |
480 | "usage: netstat [-AaBln] [-M core] [-N system] [-p protocol] [-T rtable]\n" |
481 | " netstat -W interface\n" |
482 | " netstat -m\n" |
483 | " netstat -I interface | -i [-bdehnq]\n" |
484 | " netstat -w wait [-bdehnq] [-c count] [-I interface]\n" |
485 | " netstat -s [-gru] [-f address_family] [-p protocol]\n" |
486 | " netstat -g [-lnu] [-f address_family]\n" |
487 | " netstat -R\n" |
488 | " netstat -r [-AFu] [-f address_family] [-M core] [-N system] [-T rtable]\n" |
489 | " netstat -P pcbaddr [-v] [-M core] [-N system]\n"); |
490 | exit(1); |
491 | } |
492 | |
493 | void |
494 | gettable(u_int tableid) |
495 | { |
496 | struct rt_tableinfo info; |
497 | int mib[6]; |
498 | size_t len; |
499 | |
500 | mib[0] = CTL_NET; |
501 | mib[1] = PF_ROUTE; |
502 | mib[2] = 0; |
503 | mib[3] = 0; |
504 | mib[4] = NET_RT_TABLE; |
505 | mib[5] = tableid; |
506 | |
507 | len = sizeof(info); |
508 | if (sysctl(mib, 6, &info, &len, NULL, 0) == -1) |
509 | err(1, "routing table %d", tableid); |
510 | } |