blob: cd137e586877fd7070ea666378dd4a3604c4d68e [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/*
16 Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
17
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
25
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
28
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36*/
37
38#ifdef __KERNEL__
39
Damjan Marion4dffd1c2018-09-03 12:30:36 +020040#if __linux__
Ed Warnickecb9cada2015-12-08 15:45:58 -070041# include <linux/unistd.h>
42# include <linux/signal.h>
Damjan Marion4dffd1c2018-09-03 12:30:36 +020043#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -070044
45#else /* ! __KERNEL__ */
46
Damjan Marion4dffd1c2018-09-03 12:30:36 +020047#ifdef __APPLE__
48#define _XOPEN_SOURCE
49#endif
50
Ed Warnickecb9cada2015-12-08 15:45:58 -070051#define _GNU_SOURCE /* to get REG_* in ucontext.h */
52#include <ucontext.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070053#undef __USE_GNU
54
55#include <unistd.h>
56#include <signal.h>
Damjan Mariona54230d2017-06-21 11:57:07 +020057#include <grp.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070058
59#include <time.h>
60#include <sys/socket.h>
61#include <netdb.h>
62#include <math.h>
63
64#include <vppinfra/time.h>
Damjan Marion4dffd1c2018-09-03 12:30:36 +020065#if __linux__
Ed Warnickecb9cada2015-12-08 15:45:58 -070066#ifdef AF_NETLINK
67#include <linux/types.h>
68#include <linux/netlink.h>
69#endif
Damjan Marion4dffd1c2018-09-03 12:30:36 +020070#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -070071
72#endif /* ! __KERNEL__ */
73
74
75#ifdef __KERNEL__
76# include <linux/socket.h>
77# include <linux/in.h>
78# include <linux/ip.h>
79# include <linux/tcp.h>
80# include <linux/udp.h>
81# include <linux/icmp.h>
82# include <linux/if_ether.h>
83# include <linux/if_arp.h>
84#else
85# include <net/if.h> /* struct ifnet may live here */
86# include <netinet/in.h>
87# include <netinet/ip.h>
88# include <netinet/tcp.h>
89# include <netinet/udp.h>
90# include <netinet/ip_icmp.h>
91# include <netinet/if_ether.h>
92#endif /* __KERNEL__ */
93
94#include <vppinfra/bitops.h> /* foreach_set_bit */
95#include <vppinfra/format.h>
96#include <vppinfra/error.h>
97
98/* Format unix network address family (e.g. AF_INET). */
99u8 * format_address_family (u8 * s, va_list * va)
100{
101 uword family = va_arg (*va, uword);
102 u8 * t = (u8 *) "UNKNOWN";
103 switch (family)
104 {
105#define _(x) case PF_##x: t = (u8 *) #x; break
106 _ (UNSPEC);
107 _ (UNIX); /* Unix domain sockets */
108 _ (INET); /* Internet IP Protocol */
109#ifdef PF_AX25
110 _ (AX25); /* Amateur Radio AX.25 */
111#endif
112#ifdef PF_IPX
113 _ (IPX); /* Novell IPX */
114#endif
115#ifdef PF_APPLETALK
116 _ (APPLETALK); /* AppleTalk DDP */
117#endif
118#ifdef PF_NETROM
119 _ (NETROM); /* Amateur Radio NET/ROM */
120#endif
121#ifdef PF_BRIDGE
122 _ (BRIDGE); /* Multiprotocol bridge */
123#endif
124#ifdef PF_ATMPVC
125 _ (ATMPVC); /* ATM PVCs */
126#endif
127#ifdef PF_X25
128 _ (X25); /* Reserved for X.25 project */
129#endif
130#ifdef PF_INET6
131 _ (INET6); /* IP version 6 */
132#endif
133#ifdef PF_ROSE
134 _ (ROSE); /* Amateur Radio X.25 PLP */
135#endif
136#ifdef PF_DECnet
137 _ (DECnet); /* Reserved for DECnet project */
138#endif
139#ifdef PF_NETBEUI
140 _ (NETBEUI); /* Reserved for 802.2LLC project*/
141#endif
142#ifdef PF_SECURITY
143 _ (SECURITY); /* Security callback pseudo AF */
144#endif
145#ifdef PF_KEY
146 _ (KEY); /* PF_KEY key management API */
147#endif
148#ifdef PF_NETLINK
149 _ (NETLINK);
150#endif
151#ifdef PF_PACKET
152 _ (PACKET); /* Packet family */
153#endif
154#ifdef PF_ASH
155 _ (ASH); /* Ash */
156#endif
157#ifdef PF_ECONET
158 _ (ECONET); /* Acorn Econet */
159#endif
160#ifdef PF_ATMSVC
161 _ (ATMSVC); /* ATM SVCs */
162#endif
163#ifdef PF_SNA
164 _ (SNA); /* Linux SNA Project */
165#endif
166#ifdef PF_IRDA
167 _ (IRDA); /* IRDA sockets */
168#endif
169#undef _
170 }
171 vec_add (s, t, strlen ((char *) t));
172 return s;
173}
174
175u8 * format_network_protocol (u8 * s, va_list * args)
176{
177 uword family = va_arg (*args, uword);
178 uword protocol = va_arg (*args, uword);
179
180#ifndef __KERNEL__
181 struct protoent * p = getprotobynumber (protocol);
182
183 ASSERT (family == AF_INET);
184 if (p)
185 return format (s, "%s", p->p_name);
186 else
187 return format (s, "%d", protocol);
188#else
189 return format (s, "%d/%d", family, protocol);
190#endif
191}
192
193u8 * format_network_port (u8 * s, va_list * args)
194{
195 uword proto = va_arg (*args, uword);
196 uword port = va_arg (*args, uword);
197
198#ifndef __KERNEL__
199 struct servent * p = getservbyport (port, proto == IPPROTO_UDP ? "udp" : "tcp");
200
201 if (p)
202 return format (s, "%s", p->s_name);
203 else
204 return format (s, "%d", port);
205#else
206 return format (s, "%s/%d", proto == IPPROTO_UDP ? "udp" : "tcp", port);
207#endif
208}
209
210/* Format generic network address: takes two arguments family and address.
211 Assumes network byte order. */
212u8 * format_network_address (u8 * s, va_list * args)
213{
214 uword family = va_arg (*args, uword);
215 u8 * addr = va_arg (*args, u8 *);
216
217 switch (family)
218 {
219 case AF_INET:
220 s = format (s, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
221 break;
222
223 case AF_UNSPEC:
224 /* We use AF_UNSPEC for ethernet addresses. */
225 s = format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
226 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
227 break;
228
229 default:
230 clib_error ("unsupported address family %d", family);
231 }
232
233 return s;
234}
235
236u8 * format_sockaddr (u8 * s, va_list * args)
237{
238 void * v = va_arg (*args, void *);
239 struct sockaddr * sa = v;
Dave Barachf22f07d2017-09-19 14:36:46 -0400240 static u32 local_counter;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700241
242 switch (sa->sa_family)
243 {
244 case AF_INET:
245 {
246 struct sockaddr_in * i = v;
247 s = format (s, "%U:%U",
248 format_network_address, AF_INET, &i->sin_addr.s_addr,
249 format_network_port, IPPROTO_TCP, ntohs (i->sin_port));
250 }
251 break;
252
Dave Barachf22f07d2017-09-19 14:36:46 -0400253 case AF_LOCAL:
254 {
255 /*
256 * There isn't anything useful to print.
257 * The unix cli world uses the output to make a node name,
258 * so we need to return a unique name.
259 */
260 s = format (s, "local:%u", local_counter++);
261 }
262 break;
263
Ed Warnickecb9cada2015-12-08 15:45:58 -0700264#ifndef __KERNEL__
265#ifdef AF_NETLINK
266 case AF_NETLINK:
267 {
268 struct sockaddr_nl * n = v;
269 s = format (s, "KERNEL-NETLINK");
270 if (n->nl_groups)
271 s = format (s, " (groups 0x%x)", n->nl_groups);
272 break;
273 }
274#endif
275#endif
276
277 default:
278 s = format (s, "sockaddr family %d", sa->sa_family);
279 break;
280 }
281
282 return s;
283}
284
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200285#ifndef __APPLE__
Ed Warnickecb9cada2015-12-08 15:45:58 -0700286u8 * format_tcp4_packet (u8 * s, va_list * args)
287{
288 u8 * p = va_arg (*args, u8 *);
289 struct iphdr * ip = (void *) p;
290 struct tcphdr * tcp = (void *) (ip + 1);
291
292 s = format (s, "tcp %U:%U -> %U:%U",
293 format_network_address, AF_INET, &ip->saddr,
294 format_network_port, IPPROTO_TCP, ntohs (tcp->source),
295 format_network_address, AF_INET, &ip->daddr,
296 format_network_port, IPPROTO_TCP, ntohs (tcp->dest));
297
298 s = format (s, ", seq 0x%08x -> 0x%08x", tcp->seq, tcp->ack_seq);
299#define _(f) if (tcp->f) s = format (s, ", " #f);
300 _ (syn); _ (ack); _ (fin); _ (rst); _ (psh); _ (urg);
301#undef _
302
303 if (tcp->window)
304 s = format (s, ", window 0x%04x", tcp->window);
305 if (tcp->urg)
306 s = format (s, ", urg 0x%04x", tcp->urg_ptr);
307
308 return s;
309}
310
311u8 * format_udp4_packet (u8 * s, va_list * args)
312{
313 u8 * p = va_arg (*args, u8 *);
314 struct iphdr * ip = (void *) p;
315 struct udphdr * udp = (void *) (ip + 1);
316
Nathan Moos323418d2021-01-15 16:45:14 -0800317 s = format (s, "udp %U:%U -> %U:%U", format_network_address, AF_INET,
Jieqiang Wang3f79e272021-02-10 15:16:51 +0000318 &ip->saddr, format_network_port, IPPROTO_UDP,
319 ntohs (udp->source), format_network_address, AF_INET, &ip->daddr,
320 format_network_port, IPPROTO_UDP, ntohs (udp->dest));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700321
322 return s;
323}
324
325u8 * format_icmp4_type_and_code (u8 * s, va_list * args)
326{
327 uword icmp_type = va_arg (*args, uword);
328 uword icmp_code = va_arg (*args, uword);
329
330 switch (icmp_type)
331 {
332#define _(f,str) case ICMP_##f: s = format (s, str); break;
333 _ (ECHOREPLY, "echo reply");
334 _ (DEST_UNREACH, "unreachable");
335 _ (SOURCE_QUENCH, "source quench");
336 _ (REDIRECT, "redirect");
337 _ (ECHO, "echo request");
338 _ (TIME_EXCEEDED, "time exceeded");
339 _ (PARAMETERPROB, "parameter problem");
340 _ (TIMESTAMP, "timestamp request");
341 _ (TIMESTAMPREPLY, "timestamp reply");
342 _ (INFO_REQUEST, "information request");
343 _ (INFO_REPLY, "information reply");
344 _ (ADDRESS, "address mask request");
345 _ (ADDRESSREPLY, "address mask reply");
346#undef _
347 default:
348 s = format (s, "unknown type 0x%x", icmp_type);
349 }
350
351 if (icmp_type == ICMP_DEST_UNREACH)
352 {
353 switch (icmp_code)
354 {
355#define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
356 _ (NET_UNREACH, "network");
357 _ (HOST_UNREACH, "host");
358 _ (PROT_UNREACH, "protocol");
359 _ (PORT_UNREACH, "port");
360 _ (FRAG_NEEDED, ": fragmentation needed/DF set");
361 _ (SR_FAILED, "source route failed");
362 _ (NET_UNKNOWN, "network unknown");
363 _ (HOST_UNKNOWN, "host unknown");
364 _ (HOST_ISOLATED, "host isolated");
365 _ (NET_ANO, "network: admin. prohibited");
366 _ (HOST_ANO, "host: admin. prohibited");
367 _ (NET_UNR_TOS, "network for type-of-service");
368 _ (HOST_UNR_TOS, "host for type-of-service");
369 _ (PKT_FILTERED, ": packet filtered");
370 _ (PREC_VIOLATION, "precedence violation");
371 _ (PREC_CUTOFF, "precedence cut off");
372#undef _
373 default:
374 s = format (s, "unknown code 0x%x", icmp_code);
375 }
376 }
377 else if (icmp_type == ICMP_REDIRECT)
378 {
379 switch (icmp_code)
380 {
381#define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
382 _ (REDIR_NET, "network");
383 _ (REDIR_HOST, "host");
384 _ (REDIR_NETTOS, "network for type-of-service");
385 _ (REDIR_HOSTTOS, "host for type-of-service");
386#undef _
387 default:
388 s = format (s, "unknown code 0x%x", icmp_code);
389 }
390 }
391 else if (icmp_type == ICMP_TIME_EXCEEDED)
392 {
393 switch (icmp_code)
394 {
395#define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
396 _ (EXC_TTL, "time-to-live zero in transit");
397 _ (EXC_FRAGTIME, "time-to-live zero during reassembly");
398#undef _
399 default:
400 s = format (s, "unknown code 0x%x", icmp_code);
401 }
402 }
403
404 return s;
405}
406
407typedef struct {
408 u8 type;
409 u8 code;
410 u16 checksum;
411} icmp4_t;
412
413u8 * format_icmp4_packet (u8 * s, va_list * args)
414{
415 u8 * p = va_arg (*args, u8 *);
416 struct iphdr * ip = (void *) p;
417 icmp4_t * icmp = (void *) (ip + 1);
418 s = format (s, "icmp %U %U -> %U",
419 format_icmp4_type_and_code, icmp->type, icmp->code,
420 format_network_address, AF_INET, &ip->saddr,
421 format_network_address, AF_INET, &ip->daddr);
422
423 return s;
424}
425
426u8 * format_ip4_tos_byte (u8 * s, va_list * args)
427{
428 uword tos = va_arg (*args, uword);
429
430 if (tos & IPTOS_LOWDELAY)
431 s = format (s, "minimize-delay, ");
432 if (tos & IPTOS_MINCOST)
433 s = format (s, "minimize-cost, ");
434 if (tos & IPTOS_THROUGHPUT)
435 s = format (s, "maximize-throughput, ");
436 if (tos & IPTOS_RELIABILITY)
437 s = format (s, "maximize-reliability, ");
438
439 switch (IPTOS_PREC (tos))
440 {
441#define _(x,y) case IPTOS_PREC_##x: s = format (s, y); break
442 _ (NETCONTROL, "network");
443 _ (INTERNETCONTROL, "internet");
444 _ (CRITIC_ECP, "critical");
445 _ (FLASH, "flash");
446 _ (FLASHOVERRIDE, "flash-override");
447 _ (IMMEDIATE, "immediate");
448 _ (PRIORITY, "priority");
449 _ (ROUTINE, "routine");
450#undef _
451 }
452
453 return s;
454}
455
456u8 * format_ip4_packet (u8 * s, va_list * args)
457{
458 u8 * p = va_arg (*args, u8 *);
459 struct iphdr * ip = (void *) p;
460
461 static format_function_t * f[256];
462
463 if (! f[IPPROTO_TCP])
464 {
465 f[IPPROTO_TCP] = format_tcp4_packet;
466 f[IPPROTO_UDP] = format_udp4_packet;
467 f[IPPROTO_ICMP] = format_icmp4_packet;
468 }
469
470 if (f[ip->protocol])
471 return format (s, "%U", f[ip->protocol], p);
472
473 s = format (s, "%U: %U -> %U",
474 format_network_protocol, AF_INET, ip->protocol,
475 format_network_address, AF_INET, &ip->saddr,
476 format_network_address, AF_INET, &ip->daddr);
477
478 return s;
479}
480
481#define foreach_unix_arphrd_type \
482 _ (NETROM, 0) \
483 _ (ETHER, 1) \
484 _ (EETHER, 2) \
485 _ (AX25, 3) \
486 _ (PRONET, 4) \
487 _ (CHAOS, 5) \
488 _ (IEEE802, 6) \
489 _ (ARCNET, 7) \
490 _ (APPLETLK, 8) \
491 _ (DLCI, 15) \
492 _ (ATM, 19) \
493 _ (METRICOM, 23) \
494 _ (IEEE1394, 24) \
495 _ (EUI64, 27) \
496 _ (INFINIBAND, 32) \
497 _ (SLIP, 256) \
498 _ (CSLIP, 257) \
499 _ (SLIP6, 258) \
500 _ (CSLIP6, 259) \
501 _ (RSRVD, 260) \
502 _ (ADAPT, 264) \
503 _ (ROSE, 270) \
504 _ (X25, 271) \
505 _ (HWX25, 272) \
506 _ (PPP, 512) \
507 _ (HDLC, 513) \
508 _ (LAPB, 516) \
509 _ (DDCMP, 517) \
510 _ (RAWHDLC, 518) \
511 _ (TUNNEL, 768) \
512 _ (TUNNEL6, 769) \
513 _ (FRAD, 770) \
514 _ (SKIP, 771) \
515 _ (LOOPBACK, 772) \
516 _ (LOCALTLK, 773) \
517 _ (FDDI, 774) \
518 _ (BIF, 775) \
519 _ (SIT, 776) \
520 _ (IPDDP, 777) \
521 _ (IPGRE, 778) \
522 _ (PIMREG, 779) \
523 _ (HIPPI, 780) \
524 _ (ASH, 781) \
525 _ (ECONET, 782) \
526 _ (IRDA, 783) \
527 _ (FCPP, 784) \
528 _ (FCAL, 785) \
529 _ (FCPL, 786) \
530 _ (FCFABRIC, 787) \
531 _ (IEEE802_TR, 800) \
532 _ (IEEE80211, 801) \
533 _ (IEEE80211_PRISM, 802) \
534 _ (IEEE80211_RADIOTAP, 803) \
535 _ (VOID, 0xFFFF) \
536 _ (NONE, 0xFFFE)
537
538u8 * format_unix_arphrd (u8 * s, va_list * args)
539{
540#ifndef __COVERITY__ /* doesn't understand this at all... */
541 u32 x = va_arg (*args, u32);
542 char * t;
543 switch (x)
544 {
545#define _(f,n) case ARPHRD_##f: t = #f; break;
546 foreach_unix_arphrd_type
547#undef _
548 default:
549 t = 0;
550 break;
551 }
552
553 if (t)
554 s = format (s, "%s", t);
555 else
556 s = format (s, "unknown 0x%x", x);
557#endif
558 return s;
559}
560
561#define foreach_unix_interface_flag \
562 _ (up) \
563 _ (broadcast) \
564 _ (debug) \
565 _ (loopback) \
566 _ (pointopoint) \
567 _ (notrailers) \
568 _ (running) \
569 _ (noarp) \
570 _ (promisc) \
571 _ (allmulti) \
572 _ (master) \
573 _ (slave) \
574 _ (multicast) \
575 _ (portsel) \
576 _ (automedia) \
577 _ (dynamic) \
578 _ (lower_up) \
579 _ (dormant) \
580 _ (echo)
581
582static char * unix_interface_flag_names[] = {
583#define _(f) #f,
584 foreach_unix_interface_flag
585#undef _
586};
587
588u8 * format_unix_interface_flags (u8 * s, va_list * args)
589{
590 u32 x = va_arg (*args, u32);
591 u32 i;
592
593 if (x == 0)
594 s = format (s, "none");
595 else foreach_set_bit (i, x, ({
596 if (i < ARRAY_LEN (unix_interface_flag_names))
597 s = format (s, "%s", unix_interface_flag_names[i]);
598 else
599 s = format (s, "unknown %d", i);
600 if (x >> (i + 1))
601 s = format (s, ", ");
602 }));
603 return s;
604}
605
606typedef struct {
607 u16 ar_hrd; /* format of hardware address */
608 u16 ar_pro; /* format of protocol address */
609 u8 ar_hln; /* length of hardware address */
610 u8 ar_pln; /* length of protocol address */
611 u16 ar_op; /* ARP opcode (command) */
612 u8 ar_sha[6]; /* sender hardware address */
613 u8 ar_spa[4]; /* sender IP address */
614 u8 ar_tha[6]; /* target hardware address */
615 u8 ar_tpa[4]; /* target IP address */
616} arp_ether_ip4_t;
617
618u8 * format_arp_packet (u8 * s, va_list * args)
619{
620 arp_ether_ip4_t * a = va_arg (*args, arp_ether_ip4_t *);
621 char * op = "unknown";
622
623 if (a->ar_pro != ETH_P_IP ||
624 a->ar_hrd != ARPHRD_ETHER)
625 return s;
626
627 switch (a->ar_op)
628 {
629#define _(f) case ARPOP_##f: op = #f; break;
630 _ (REQUEST);
631 _ (REPLY);
632 _ (RREQUEST);
633 _ (RREPLY);
634#undef _
635 }
636
637 s = format (s, "%s %U %U -> %U %U",
638 op,
639 format_network_address, AF_INET, a->ar_spa,
640 format_network_address, AF_UNSPEC, a->ar_sha,
641 format_network_address, AF_INET, a->ar_tpa,
642 format_network_address, AF_UNSPEC, a->ar_tha);
643 return s;
644}
645
646u8 * format_ethernet_proto (u8 * s, va_list * args)
647{
648 uword type = va_arg (*args, uword);
649 char * t = 0;
650
651 switch (type)
652 {
653 case 0: t = "BPDU"; break;
654#define _(f) case ETH_P_##f: t = #f; break;
655 _ (LOOP);
656 _ (PUP);
657#ifdef ETH_P_PUPAT
658 _ (PUPAT);
659#endif
660 _ (IP);
661 _ (X25);
662 _ (ARP);
663 _ (BPQ);
664#ifdef ETH_P_PUPAT
665 _ (IEEEPUP);
666 _ (IEEEPUPAT);
667#endif
668 _ (DEC);
669 _ (DNA_DL);
670 _ (DNA_RC);
671 _ (DNA_RT);
672 _ (LAT);
673 _ (DIAG);
674 _ (CUST);
675 _ (SCA);
676 _ (RARP);
677 _ (ATALK);
678 _ (AARP);
679 _ (IPX);
680 _ (IPV6);
681#ifdef ETH_P_PPP_DISC
682 _ (PPP_DISC);
683 _ (PPP_SES);
684#endif
685#ifdef ETH_P_ATMMPOA
686 _ (ATMMPOA);
687 _ (ATMFATE);
688#endif
689 _ (802_3);
690 _ (AX25);
691 _ (ALL);
692 _ (802_2);
693 _ (SNAP);
694 _ (DDCMP);
695 _ (WAN_PPP);
696 _ (PPP_MP);
697 _ (LOCALTALK);
698 _ (PPPTALK);
699 _ (TR_802_2);
700 _ (MOBITEX);
701 _ (CONTROL);
702 _ (IRDA);
703#ifdef ETH_P_ECONET
704 _ (ECONET);
705#endif
706#undef _
707 }
708
709 if (t)
710 vec_add (s, t, strlen (t));
711 else
712 s = format (s, "ether-type 0x%x", type);
713 return s;
714}
715
716u8 * format_ethernet_packet (u8 * s, va_list * args)
717{
718 struct ethhdr * h = va_arg (*args, struct ethhdr *);
719 uword proto = h->h_proto;
720 u8 * payload = (void *) (h + 1);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200721 u32 indent;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700722
723 /* Check for 802.2/802.3 encapsulation. */
724 if (proto < ETH_DATA_LEN)
725 {
726 typedef struct {
727 u8 dsap, ssap, control;
728 u8 orig_code[3];
729 u16 proto;
730 } ethhdr_802_t;
731 ethhdr_802_t * h1 = (void *) (h + 1);
732 proto = h1->proto;
733 payload = (void *) (h1 + 1);
734 }
735
736 indent = format_get_indent (s);
737
738 s = format (s, "%U: %U -> %U",
739 format_ethernet_proto, proto,
740 format_network_address, AF_UNSPEC, h->h_source,
741 format_network_address, AF_UNSPEC, h->h_dest);
742
743 switch (proto)
744 {
745 case ETH_P_ARP:
746 s = format (s, "\n%U%U",
747 format_white_space, indent,
748 format_arp_packet, payload);
749 break;
750 }
751
752 return s;
753}
754
755#ifndef __KERNEL__
756u8 * format_hostname (u8 * s, va_list * args)
757{
758 char buffer[1024];
759 char * b = buffer;
760 if (gethostname (b, sizeof (buffer)) < 0)
761 b = "noname";
762 return format (s, "%s", b);
763}
764#endif
765
766#ifndef __KERNEL__
767u8 * format_timeval (u8 * s, va_list * args)
768{
769 char * fmt = va_arg (*args, char *);
770 struct timeval * tv = va_arg (*args, struct timeval *);
771 struct tm * tm;
772 word msec;
773 char * f, c;
774
775 if (! fmt)
776 fmt = "y/m/d H:M:S:F";
777
778 if (! tv)
779 {
780 static struct timeval now;
781 gettimeofday (&now, 0);
782 tv = &now;
783 }
784
785 msec = flt_round_nearest (1e-3 * tv->tv_usec);
786 if (msec >= 1000)
787 { msec = 0; tv->tv_sec++; }
788
789 {
790 time_t t = tv->tv_sec;
791 tm = localtime (&t);
792 }
793
794 for (f = fmt; *f; f++)
795 {
796 uword what;
797 char * what_fmt = "%d";
798
799 switch (c = *f)
800 {
801 default:
802 vec_add1 (s, c);
803 continue;
804
805 case 'y':
806 what = 1900 + tm->tm_year;
807 what_fmt = "%4d";
808 break;
809 case 'm':
810 what = tm->tm_mon + 1;
Paul Vinciguerra27826302019-05-09 19:12:18 -0400811 what_fmt = "%02d";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700812 break;
813 case 'd':
814 what = tm->tm_mday;
Paul Vinciguerra27826302019-05-09 19:12:18 -0400815 what_fmt = "%02d";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700816 break;
817 case 'H':
818 what = tm->tm_hour;
819 what_fmt = "%02d";
820 break;
821 case 'M':
822 what = tm->tm_min;
823 what_fmt = "%02d";
824 break;
825 case 'S':
826 what = tm->tm_sec;
827 what_fmt = "%02d";
828 break;
829 case 'F':
830 what = msec;
831 what_fmt = "%03d";
832 break;
833 }
834
835 s = format (s, what_fmt, what);
836 }
837
838 return s;
839}
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200840#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700841
842u8 * format_time_float (u8 * s, va_list * args)
843{
844 u8 * fmt = va_arg (*args, u8 *);
845 f64 t = va_arg (*args, f64);
846 struct timeval tv;
847 if (t <= 0)
848 t = unix_time_now ();
849 tv.tv_sec = t;
850 tv.tv_usec = 1e6*(t - tv.tv_sec);
851 return format (s, "%U", format_timeval, fmt, &tv);
852}
853
854u8 * format_signal (u8 * s, va_list * args)
855{
856 uword signum = va_arg (*args, uword);
857 char * t = 0;
858 switch (signum)
859 {
860#define _(x) case x: t = #x; break;
861 _ (SIGHUP);
862 _ (SIGINT);
863 _ (SIGQUIT);
864 _ (SIGILL);
865 _ (SIGTRAP);
866 _ (SIGABRT);
867 _ (SIGBUS);
868 _ (SIGFPE);
869 _ (SIGKILL);
870 _ (SIGUSR1);
871 _ (SIGSEGV);
872 _ (SIGUSR2);
873 _ (SIGPIPE);
874 _ (SIGALRM);
875 _ (SIGTERM);
876#ifdef SIGSTKFLT
877 _ (SIGSTKFLT);
878#endif
879 _ (SIGCHLD);
880 _ (SIGCONT);
881 _ (SIGSTOP);
882 _ (SIGTSTP);
883 _ (SIGTTIN);
884 _ (SIGTTOU);
885 _ (SIGURG);
886 _ (SIGXCPU);
887 _ (SIGXFSZ);
888 _ (SIGVTALRM);
889 _ (SIGPROF);
890 _ (SIGWINCH);
891 _ (SIGIO);
892 _ (SIGPWR);
893#ifdef SIGSYS
894 _ (SIGSYS);
895#endif
896#undef _
897 default:
898 return format (s, "unknown %d", signum);
899 }
900
901 vec_add (s, t, strlen (t));
902 return s;
903}
904
905u8 * format_ucontext_pc (u8 * s, va_list * args)
906{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500907 ucontext_t * uc __attribute__((unused));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700908 unsigned long * regs = 0;
909 uword reg_no = 0;
910
Dave Barachbfdedbd2016-01-20 09:11:55 -0500911 uc = va_arg (*args, ucontext_t *);
912
Ed Warnickecb9cada2015-12-08 15:45:58 -0700913#if defined (powerpc)
914 regs = &uc->uc_mcontext.uc_regs->gregs[0];
915#elif defined (powerpc64)
916 regs = &uc->uc_mcontext.uc_regs->gp_regs[0];
917#elif defined (i386) || defined (__x86_64__)
918 regs = (void *) &uc->uc_mcontext.gregs[0];
919#endif
920
921#if defined (powerpc) || defined (powerpc64)
922 reg_no = PT_NIP;
923#elif defined (i386)
924 reg_no = REG_EIP;
925#elif defined (__x86_64__)
926 reg_no = REG_RIP;
927#else
928 reg_no = 0;
929 regs = 0;
930#endif
931
932 if (! regs)
933 return format (s, "unsupported");
934 else
935 return format (s, "%p", regs[reg_no]);
936}
937
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200938__clib_export uword
Damjan Mariona54230d2017-06-21 11:57:07 +0200939unformat_unix_gid (unformat_input_t * input, va_list * args)
940{
941 gid_t *gid = va_arg (*args, gid_t *);
942 struct group *grp = 0;
943 int r;
944 u8 *s;
945
946 if (unformat (input, "%d", &r))
947 {
948 grp = getgrgid (r);
949 }
950 else if (unformat (input, "%s", &s))
951 {
952 grp = getgrnam ((char *) s);
953 vec_free (s);
954 }
955 if (grp)
956 {
957 *gid = grp->gr_gid;
958 return 1;
959 }
960 return 0;
961}
962
Ed Warnickecb9cada2015-12-08 15:45:58 -0700963#endif /* __KERNEL__ */