919865161086b8fa30fd1ffd0f237283babf7601
[vpp.git] / src / 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 #include <grp.h>
53
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). */
93 u8 * 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
169 u8 * 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
187 u8 * 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. */
206 u8 * 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
230 u8 * 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
267 u8 * 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
292 u8 * 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
307 u8 * 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
389 typedef struct {
390   u8 type;
391   u8 code;
392   u16 checksum;
393 } icmp4_t;
394
395 u8 * 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
408 u8 * 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
438 u8 * 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
520 u8 * 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
564 static char * unix_interface_flag_names[] = {
565 #define _(f) #f,
566   foreach_unix_interface_flag
567 #undef _
568 };
569
570 u8 * 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
588 typedef 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
600 u8 * 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
628 u8 * 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
698 u8 * 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__
738 u8 * 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__
749 u8 * 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
823 u8 * 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
835 u8 * 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
886 u8 * format_ucontext_pc (u8 * s, va_list * args)
887 {
888   ucontext_t * uc __attribute__((unused));
889   unsigned long * regs = 0;
890   uword reg_no = 0;
891
892   uc = va_arg (*args, ucontext_t *);
893
894 #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
919 uword
920 unformat_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
944 #endif /* __KERNEL__ */