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