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