blob: eceea2d25be75294bcc7a445e429a7e6d19c28fd [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;
Dave Barachf22f07d2017-09-19 14:36:46 -0400234 static u32 local_counter;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700235
236 switch (sa->sa_family)
237 {
238 case AF_INET:
239 {
240 struct sockaddr_in * i = v;
241 s = format (s, "%U:%U",
242 format_network_address, AF_INET, &i->sin_addr.s_addr,
243 format_network_port, IPPROTO_TCP, ntohs (i->sin_port));
244 }
245 break;
246
Dave Barachf22f07d2017-09-19 14:36:46 -0400247 case AF_LOCAL:
248 {
249 /*
250 * There isn't anything useful to print.
251 * The unix cli world uses the output to make a node name,
252 * so we need to return a unique name.
253 */
254 s = format (s, "local:%u", local_counter++);
255 }
256 break;
257
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258#ifndef __KERNEL__
259#ifdef AF_NETLINK
260 case AF_NETLINK:
261 {
262 struct sockaddr_nl * n = v;
263 s = format (s, "KERNEL-NETLINK");
264 if (n->nl_groups)
265 s = format (s, " (groups 0x%x)", n->nl_groups);
266 break;
267 }
268#endif
269#endif
270
271 default:
272 s = format (s, "sockaddr family %d", sa->sa_family);
273 break;
274 }
275
276 return s;
277}
278
279u8 * format_tcp4_packet (u8 * s, va_list * args)
280{
281 u8 * p = va_arg (*args, u8 *);
282 struct iphdr * ip = (void *) p;
283 struct tcphdr * tcp = (void *) (ip + 1);
284
285 s = format (s, "tcp %U:%U -> %U:%U",
286 format_network_address, AF_INET, &ip->saddr,
287 format_network_port, IPPROTO_TCP, ntohs (tcp->source),
288 format_network_address, AF_INET, &ip->daddr,
289 format_network_port, IPPROTO_TCP, ntohs (tcp->dest));
290
291 s = format (s, ", seq 0x%08x -> 0x%08x", tcp->seq, tcp->ack_seq);
292#define _(f) if (tcp->f) s = format (s, ", " #f);
293 _ (syn); _ (ack); _ (fin); _ (rst); _ (psh); _ (urg);
294#undef _
295
296 if (tcp->window)
297 s = format (s, ", window 0x%04x", tcp->window);
298 if (tcp->urg)
299 s = format (s, ", urg 0x%04x", tcp->urg_ptr);
300
301 return s;
302}
303
304u8 * format_udp4_packet (u8 * s, va_list * args)
305{
306 u8 * p = va_arg (*args, u8 *);
307 struct iphdr * ip = (void *) p;
308 struct udphdr * udp = (void *) (ip + 1);
309
310 s = format (s, "udp %U:%U -> %U:%U",
311 format_network_address, AF_INET, &ip->saddr,
312 format_network_port, IPPROTO_UDP, ntohs (udp->source),
313 format_network_address, AF_INET, &ip->daddr,
314 format_network_port, IPPROTO_UDP, ntohs (udp->dest));
315
316 return s;
317}
318
319u8 * format_icmp4_type_and_code (u8 * s, va_list * args)
320{
321 uword icmp_type = va_arg (*args, uword);
322 uword icmp_code = va_arg (*args, uword);
323
324 switch (icmp_type)
325 {
326#define _(f,str) case ICMP_##f: s = format (s, str); break;
327 _ (ECHOREPLY, "echo reply");
328 _ (DEST_UNREACH, "unreachable");
329 _ (SOURCE_QUENCH, "source quench");
330 _ (REDIRECT, "redirect");
331 _ (ECHO, "echo request");
332 _ (TIME_EXCEEDED, "time exceeded");
333 _ (PARAMETERPROB, "parameter problem");
334 _ (TIMESTAMP, "timestamp request");
335 _ (TIMESTAMPREPLY, "timestamp reply");
336 _ (INFO_REQUEST, "information request");
337 _ (INFO_REPLY, "information reply");
338 _ (ADDRESS, "address mask request");
339 _ (ADDRESSREPLY, "address mask reply");
340#undef _
341 default:
342 s = format (s, "unknown type 0x%x", icmp_type);
343 }
344
345 if (icmp_type == ICMP_DEST_UNREACH)
346 {
347 switch (icmp_code)
348 {
349#define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
350 _ (NET_UNREACH, "network");
351 _ (HOST_UNREACH, "host");
352 _ (PROT_UNREACH, "protocol");
353 _ (PORT_UNREACH, "port");
354 _ (FRAG_NEEDED, ": fragmentation needed/DF set");
355 _ (SR_FAILED, "source route failed");
356 _ (NET_UNKNOWN, "network unknown");
357 _ (HOST_UNKNOWN, "host unknown");
358 _ (HOST_ISOLATED, "host isolated");
359 _ (NET_ANO, "network: admin. prohibited");
360 _ (HOST_ANO, "host: admin. prohibited");
361 _ (NET_UNR_TOS, "network for type-of-service");
362 _ (HOST_UNR_TOS, "host for type-of-service");
363 _ (PKT_FILTERED, ": packet filtered");
364 _ (PREC_VIOLATION, "precedence violation");
365 _ (PREC_CUTOFF, "precedence cut off");
366#undef _
367 default:
368 s = format (s, "unknown code 0x%x", icmp_code);
369 }
370 }
371 else if (icmp_type == ICMP_REDIRECT)
372 {
373 switch (icmp_code)
374 {
375#define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
376 _ (REDIR_NET, "network");
377 _ (REDIR_HOST, "host");
378 _ (REDIR_NETTOS, "network for type-of-service");
379 _ (REDIR_HOSTTOS, "host for type-of-service");
380#undef _
381 default:
382 s = format (s, "unknown code 0x%x", icmp_code);
383 }
384 }
385 else if (icmp_type == ICMP_TIME_EXCEEDED)
386 {
387 switch (icmp_code)
388 {
389#define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
390 _ (EXC_TTL, "time-to-live zero in transit");
391 _ (EXC_FRAGTIME, "time-to-live zero during reassembly");
392#undef _
393 default:
394 s = format (s, "unknown code 0x%x", icmp_code);
395 }
396 }
397
398 return s;
399}
400
401typedef struct {
402 u8 type;
403 u8 code;
404 u16 checksum;
405} icmp4_t;
406
407u8 * format_icmp4_packet (u8 * s, va_list * args)
408{
409 u8 * p = va_arg (*args, u8 *);
410 struct iphdr * ip = (void *) p;
411 icmp4_t * icmp = (void *) (ip + 1);
412 s = format (s, "icmp %U %U -> %U",
413 format_icmp4_type_and_code, icmp->type, icmp->code,
414 format_network_address, AF_INET, &ip->saddr,
415 format_network_address, AF_INET, &ip->daddr);
416
417 return s;
418}
419
420u8 * format_ip4_tos_byte (u8 * s, va_list * args)
421{
422 uword tos = va_arg (*args, uword);
423
424 if (tos & IPTOS_LOWDELAY)
425 s = format (s, "minimize-delay, ");
426 if (tos & IPTOS_MINCOST)
427 s = format (s, "minimize-cost, ");
428 if (tos & IPTOS_THROUGHPUT)
429 s = format (s, "maximize-throughput, ");
430 if (tos & IPTOS_RELIABILITY)
431 s = format (s, "maximize-reliability, ");
432
433 switch (IPTOS_PREC (tos))
434 {
435#define _(x,y) case IPTOS_PREC_##x: s = format (s, y); break
436 _ (NETCONTROL, "network");
437 _ (INTERNETCONTROL, "internet");
438 _ (CRITIC_ECP, "critical");
439 _ (FLASH, "flash");
440 _ (FLASHOVERRIDE, "flash-override");
441 _ (IMMEDIATE, "immediate");
442 _ (PRIORITY, "priority");
443 _ (ROUTINE, "routine");
444#undef _
445 }
446
447 return s;
448}
449
450u8 * format_ip4_packet (u8 * s, va_list * args)
451{
452 u8 * p = va_arg (*args, u8 *);
453 struct iphdr * ip = (void *) p;
454
455 static format_function_t * f[256];
456
457 if (! f[IPPROTO_TCP])
458 {
459 f[IPPROTO_TCP] = format_tcp4_packet;
460 f[IPPROTO_UDP] = format_udp4_packet;
461 f[IPPROTO_ICMP] = format_icmp4_packet;
462 }
463
464 if (f[ip->protocol])
465 return format (s, "%U", f[ip->protocol], p);
466
467 s = format (s, "%U: %U -> %U",
468 format_network_protocol, AF_INET, ip->protocol,
469 format_network_address, AF_INET, &ip->saddr,
470 format_network_address, AF_INET, &ip->daddr);
471
472 return s;
473}
474
475#define foreach_unix_arphrd_type \
476 _ (NETROM, 0) \
477 _ (ETHER, 1) \
478 _ (EETHER, 2) \
479 _ (AX25, 3) \
480 _ (PRONET, 4) \
481 _ (CHAOS, 5) \
482 _ (IEEE802, 6) \
483 _ (ARCNET, 7) \
484 _ (APPLETLK, 8) \
485 _ (DLCI, 15) \
486 _ (ATM, 19) \
487 _ (METRICOM, 23) \
488 _ (IEEE1394, 24) \
489 _ (EUI64, 27) \
490 _ (INFINIBAND, 32) \
491 _ (SLIP, 256) \
492 _ (CSLIP, 257) \
493 _ (SLIP6, 258) \
494 _ (CSLIP6, 259) \
495 _ (RSRVD, 260) \
496 _ (ADAPT, 264) \
497 _ (ROSE, 270) \
498 _ (X25, 271) \
499 _ (HWX25, 272) \
500 _ (PPP, 512) \
501 _ (HDLC, 513) \
502 _ (LAPB, 516) \
503 _ (DDCMP, 517) \
504 _ (RAWHDLC, 518) \
505 _ (TUNNEL, 768) \
506 _ (TUNNEL6, 769) \
507 _ (FRAD, 770) \
508 _ (SKIP, 771) \
509 _ (LOOPBACK, 772) \
510 _ (LOCALTLK, 773) \
511 _ (FDDI, 774) \
512 _ (BIF, 775) \
513 _ (SIT, 776) \
514 _ (IPDDP, 777) \
515 _ (IPGRE, 778) \
516 _ (PIMREG, 779) \
517 _ (HIPPI, 780) \
518 _ (ASH, 781) \
519 _ (ECONET, 782) \
520 _ (IRDA, 783) \
521 _ (FCPP, 784) \
522 _ (FCAL, 785) \
523 _ (FCPL, 786) \
524 _ (FCFABRIC, 787) \
525 _ (IEEE802_TR, 800) \
526 _ (IEEE80211, 801) \
527 _ (IEEE80211_PRISM, 802) \
528 _ (IEEE80211_RADIOTAP, 803) \
529 _ (VOID, 0xFFFF) \
530 _ (NONE, 0xFFFE)
531
532u8 * format_unix_arphrd (u8 * s, va_list * args)
533{
534#ifndef __COVERITY__ /* doesn't understand this at all... */
535 u32 x = va_arg (*args, u32);
536 char * t;
537 switch (x)
538 {
539#define _(f,n) case ARPHRD_##f: t = #f; break;
540 foreach_unix_arphrd_type
541#undef _
542 default:
543 t = 0;
544 break;
545 }
546
547 if (t)
548 s = format (s, "%s", t);
549 else
550 s = format (s, "unknown 0x%x", x);
551#endif
552 return s;
553}
554
555#define foreach_unix_interface_flag \
556 _ (up) \
557 _ (broadcast) \
558 _ (debug) \
559 _ (loopback) \
560 _ (pointopoint) \
561 _ (notrailers) \
562 _ (running) \
563 _ (noarp) \
564 _ (promisc) \
565 _ (allmulti) \
566 _ (master) \
567 _ (slave) \
568 _ (multicast) \
569 _ (portsel) \
570 _ (automedia) \
571 _ (dynamic) \
572 _ (lower_up) \
573 _ (dormant) \
574 _ (echo)
575
576static char * unix_interface_flag_names[] = {
577#define _(f) #f,
578 foreach_unix_interface_flag
579#undef _
580};
581
582u8 * format_unix_interface_flags (u8 * s, va_list * args)
583{
584 u32 x = va_arg (*args, u32);
585 u32 i;
586
587 if (x == 0)
588 s = format (s, "none");
589 else foreach_set_bit (i, x, ({
590 if (i < ARRAY_LEN (unix_interface_flag_names))
591 s = format (s, "%s", unix_interface_flag_names[i]);
592 else
593 s = format (s, "unknown %d", i);
594 if (x >> (i + 1))
595 s = format (s, ", ");
596 }));
597 return s;
598}
599
600typedef struct {
601 u16 ar_hrd; /* format of hardware address */
602 u16 ar_pro; /* format of protocol address */
603 u8 ar_hln; /* length of hardware address */
604 u8 ar_pln; /* length of protocol address */
605 u16 ar_op; /* ARP opcode (command) */
606 u8 ar_sha[6]; /* sender hardware address */
607 u8 ar_spa[4]; /* sender IP address */
608 u8 ar_tha[6]; /* target hardware address */
609 u8 ar_tpa[4]; /* target IP address */
610} arp_ether_ip4_t;
611
612u8 * format_arp_packet (u8 * s, va_list * args)
613{
614 arp_ether_ip4_t * a = va_arg (*args, arp_ether_ip4_t *);
615 char * op = "unknown";
616
617 if (a->ar_pro != ETH_P_IP ||
618 a->ar_hrd != ARPHRD_ETHER)
619 return s;
620
621 switch (a->ar_op)
622 {
623#define _(f) case ARPOP_##f: op = #f; break;
624 _ (REQUEST);
625 _ (REPLY);
626 _ (RREQUEST);
627 _ (RREPLY);
628#undef _
629 }
630
631 s = format (s, "%s %U %U -> %U %U",
632 op,
633 format_network_address, AF_INET, a->ar_spa,
634 format_network_address, AF_UNSPEC, a->ar_sha,
635 format_network_address, AF_INET, a->ar_tpa,
636 format_network_address, AF_UNSPEC, a->ar_tha);
637 return s;
638}
639
640u8 * format_ethernet_proto (u8 * s, va_list * args)
641{
642 uword type = va_arg (*args, uword);
643 char * t = 0;
644
645 switch (type)
646 {
647 case 0: t = "BPDU"; break;
648#define _(f) case ETH_P_##f: t = #f; break;
649 _ (LOOP);
650 _ (PUP);
651#ifdef ETH_P_PUPAT
652 _ (PUPAT);
653#endif
654 _ (IP);
655 _ (X25);
656 _ (ARP);
657 _ (BPQ);
658#ifdef ETH_P_PUPAT
659 _ (IEEEPUP);
660 _ (IEEEPUPAT);
661#endif
662 _ (DEC);
663 _ (DNA_DL);
664 _ (DNA_RC);
665 _ (DNA_RT);
666 _ (LAT);
667 _ (DIAG);
668 _ (CUST);
669 _ (SCA);
670 _ (RARP);
671 _ (ATALK);
672 _ (AARP);
673 _ (IPX);
674 _ (IPV6);
675#ifdef ETH_P_PPP_DISC
676 _ (PPP_DISC);
677 _ (PPP_SES);
678#endif
679#ifdef ETH_P_ATMMPOA
680 _ (ATMMPOA);
681 _ (ATMFATE);
682#endif
683 _ (802_3);
684 _ (AX25);
685 _ (ALL);
686 _ (802_2);
687 _ (SNAP);
688 _ (DDCMP);
689 _ (WAN_PPP);
690 _ (PPP_MP);
691 _ (LOCALTALK);
692 _ (PPPTALK);
693 _ (TR_802_2);
694 _ (MOBITEX);
695 _ (CONTROL);
696 _ (IRDA);
697#ifdef ETH_P_ECONET
698 _ (ECONET);
699#endif
700#undef _
701 }
702
703 if (t)
704 vec_add (s, t, strlen (t));
705 else
706 s = format (s, "ether-type 0x%x", type);
707 return s;
708}
709
710u8 * format_ethernet_packet (u8 * s, va_list * args)
711{
712 struct ethhdr * h = va_arg (*args, struct ethhdr *);
713 uword proto = h->h_proto;
714 u8 * payload = (void *) (h + 1);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200715 u32 indent;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700716
717 /* Check for 802.2/802.3 encapsulation. */
718 if (proto < ETH_DATA_LEN)
719 {
720 typedef struct {
721 u8 dsap, ssap, control;
722 u8 orig_code[3];
723 u16 proto;
724 } ethhdr_802_t;
725 ethhdr_802_t * h1 = (void *) (h + 1);
726 proto = h1->proto;
727 payload = (void *) (h1 + 1);
728 }
729
730 indent = format_get_indent (s);
731
732 s = format (s, "%U: %U -> %U",
733 format_ethernet_proto, proto,
734 format_network_address, AF_UNSPEC, h->h_source,
735 format_network_address, AF_UNSPEC, h->h_dest);
736
737 switch (proto)
738 {
739 case ETH_P_ARP:
740 s = format (s, "\n%U%U",
741 format_white_space, indent,
742 format_arp_packet, payload);
743 break;
744 }
745
746 return s;
747}
748
749#ifndef __KERNEL__
750u8 * format_hostname (u8 * s, va_list * args)
751{
752 char buffer[1024];
753 char * b = buffer;
754 if (gethostname (b, sizeof (buffer)) < 0)
755 b = "noname";
756 return format (s, "%s", b);
757}
758#endif
759
760#ifndef __KERNEL__
761u8 * format_timeval (u8 * s, va_list * args)
762{
763 char * fmt = va_arg (*args, char *);
764 struct timeval * tv = va_arg (*args, struct timeval *);
765 struct tm * tm;
766 word msec;
767 char * f, c;
768
769 if (! fmt)
770 fmt = "y/m/d H:M:S:F";
771
772 if (! tv)
773 {
774 static struct timeval now;
775 gettimeofday (&now, 0);
776 tv = &now;
777 }
778
779 msec = flt_round_nearest (1e-3 * tv->tv_usec);
780 if (msec >= 1000)
781 { msec = 0; tv->tv_sec++; }
782
783 {
784 time_t t = tv->tv_sec;
785 tm = localtime (&t);
786 }
787
788 for (f = fmt; *f; f++)
789 {
790 uword what;
791 char * what_fmt = "%d";
792
793 switch (c = *f)
794 {
795 default:
796 vec_add1 (s, c);
797 continue;
798
799 case 'y':
800 what = 1900 + tm->tm_year;
801 what_fmt = "%4d";
802 break;
803 case 'm':
804 what = tm->tm_mon + 1;
805 what_fmt = "%2d";
806 break;
807 case 'd':
808 what = tm->tm_mday;
809 what_fmt = "%2d";
810 break;
811 case 'H':
812 what = tm->tm_hour;
813 what_fmt = "%02d";
814 break;
815 case 'M':
816 what = tm->tm_min;
817 what_fmt = "%02d";
818 break;
819 case 'S':
820 what = tm->tm_sec;
821 what_fmt = "%02d";
822 break;
823 case 'F':
824 what = msec;
825 what_fmt = "%03d";
826 break;
827 }
828
829 s = format (s, what_fmt, what);
830 }
831
832 return s;
833}
834
835u8 * format_time_float (u8 * s, va_list * args)
836{
837 u8 * fmt = va_arg (*args, u8 *);
838 f64 t = va_arg (*args, f64);
839 struct timeval tv;
840 if (t <= 0)
841 t = unix_time_now ();
842 tv.tv_sec = t;
843 tv.tv_usec = 1e6*(t - tv.tv_sec);
844 return format (s, "%U", format_timeval, fmt, &tv);
845}
846
847u8 * format_signal (u8 * s, va_list * args)
848{
849 uword signum = va_arg (*args, uword);
850 char * t = 0;
851 switch (signum)
852 {
853#define _(x) case x: t = #x; break;
854 _ (SIGHUP);
855 _ (SIGINT);
856 _ (SIGQUIT);
857 _ (SIGILL);
858 _ (SIGTRAP);
859 _ (SIGABRT);
860 _ (SIGBUS);
861 _ (SIGFPE);
862 _ (SIGKILL);
863 _ (SIGUSR1);
864 _ (SIGSEGV);
865 _ (SIGUSR2);
866 _ (SIGPIPE);
867 _ (SIGALRM);
868 _ (SIGTERM);
869#ifdef SIGSTKFLT
870 _ (SIGSTKFLT);
871#endif
872 _ (SIGCHLD);
873 _ (SIGCONT);
874 _ (SIGSTOP);
875 _ (SIGTSTP);
876 _ (SIGTTIN);
877 _ (SIGTTOU);
878 _ (SIGURG);
879 _ (SIGXCPU);
880 _ (SIGXFSZ);
881 _ (SIGVTALRM);
882 _ (SIGPROF);
883 _ (SIGWINCH);
884 _ (SIGIO);
885 _ (SIGPWR);
886#ifdef SIGSYS
887 _ (SIGSYS);
888#endif
889#undef _
890 default:
891 return format (s, "unknown %d", signum);
892 }
893
894 vec_add (s, t, strlen (t));
895 return s;
896}
897
898u8 * format_ucontext_pc (u8 * s, va_list * args)
899{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500900 ucontext_t * uc __attribute__((unused));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700901 unsigned long * regs = 0;
902 uword reg_no = 0;
903
Dave Barachbfdedbd2016-01-20 09:11:55 -0500904 uc = va_arg (*args, ucontext_t *);
905
Ed Warnickecb9cada2015-12-08 15:45:58 -0700906#if defined (powerpc)
907 regs = &uc->uc_mcontext.uc_regs->gregs[0];
908#elif defined (powerpc64)
909 regs = &uc->uc_mcontext.uc_regs->gp_regs[0];
910#elif defined (i386) || defined (__x86_64__)
911 regs = (void *) &uc->uc_mcontext.gregs[0];
912#endif
913
914#if defined (powerpc) || defined (powerpc64)
915 reg_no = PT_NIP;
916#elif defined (i386)
917 reg_no = REG_EIP;
918#elif defined (__x86_64__)
919 reg_no = REG_RIP;
920#else
921 reg_no = 0;
922 regs = 0;
923#endif
924
925 if (! regs)
926 return format (s, "unsupported");
927 else
928 return format (s, "%p", regs[reg_no]);
929}
930
Damjan Mariona54230d2017-06-21 11:57:07 +0200931uword
932unformat_unix_gid (unformat_input_t * input, va_list * args)
933{
934 gid_t *gid = va_arg (*args, gid_t *);
935 struct group *grp = 0;
936 int r;
937 u8 *s;
938
939 if (unformat (input, "%d", &r))
940 {
941 grp = getgrgid (r);
942 }
943 else if (unformat (input, "%s", &s))
944 {
945 grp = getgrnam ((char *) s);
946 vec_free (s);
947 }
948 if (grp)
949 {
950 *gid = grp->gr_gid;
951 return 1;
952 }
953 return 0;
954}
955
Ed Warnickecb9cada2015-12-08 15:45:58 -0700956#endif /* __KERNEL__ */