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