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