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