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