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