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