a4c81ca2f70de93b856cb004181b1d01f6e38dce
[vpp.git] / vppinfra / vppinfra / unix-formats.c
1 /*
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). */
92 u8 * 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
168 u8 * 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
186 u8 * 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. */
205 u8 * 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
229 u8 * 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
266 u8 * 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
291 u8 * 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
306 u8 * 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
388 typedef struct {
389   u8 type;
390   u8 code;
391   u16 checksum;
392 } icmp4_t;
393
394 u8 * 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
407 u8 * 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
437 u8 * 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
519 u8 * 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
563 static char * unix_interface_flag_names[] = {
564 #define _(f) #f,
565   foreach_unix_interface_flag
566 #undef _
567 };
568
569 u8 * 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
587 typedef 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
599 u8 * 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
627 u8 * 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
697 u8 * 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__
737 u8 * 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__
748 u8 * 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
822 u8 * 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
834 u8 * 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
885 u8 * format_ucontext_pc (u8 * s, va_list * args)
886 {
887   ucontext_t * uc __attribute__((unused));
888   unsigned long * regs = 0;
889   uword reg_no = 0;
890
891   uc = va_arg (*args, ucontext_t *);
892
893 #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__ */