FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
unix-formats.c
Go to the documentation of this file.
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  static u32 local_counter;
235 
236  switch (sa->sa_family)
237  {
238  case AF_INET:
239  {
240  struct sockaddr_in * i = v;
241  s = format (s, "%U:%U",
242  format_network_address, AF_INET, &i->sin_addr.s_addr,
243  format_network_port, IPPROTO_TCP, ntohs (i->sin_port));
244  }
245  break;
246 
247  case AF_LOCAL:
248  {
249  /*
250  * There isn't anything useful to print.
251  * The unix cli world uses the output to make a node name,
252  * so we need to return a unique name.
253  */
254  s = format (s, "local:%u", local_counter++);
255  }
256  break;
257 
258 #ifndef __KERNEL__
259 #ifdef AF_NETLINK
260  case AF_NETLINK:
261  {
262  struct sockaddr_nl * n = v;
263  s = format (s, "KERNEL-NETLINK");
264  if (n->nl_groups)
265  s = format (s, " (groups 0x%x)", n->nl_groups);
266  break;
267  }
268 #endif
269 #endif
270 
271  default:
272  s = format (s, "sockaddr family %d", sa->sa_family);
273  break;
274  }
275 
276  return s;
277 }
278 
279 u8 * format_tcp4_packet (u8 * s, va_list * args)
280 {
281  u8 * p = va_arg (*args, u8 *);
282  struct iphdr * ip = (void *) p;
283  struct tcphdr * tcp = (void *) (ip + 1);
284 
285  s = format (s, "tcp %U:%U -> %U:%U",
286  format_network_address, AF_INET, &ip->saddr,
287  format_network_port, IPPROTO_TCP, ntohs (tcp->source),
288  format_network_address, AF_INET, &ip->daddr,
289  format_network_port, IPPROTO_TCP, ntohs (tcp->dest));
290 
291  s = format (s, ", seq 0x%08x -> 0x%08x", tcp->seq, tcp->ack_seq);
292 #define _(f) if (tcp->f) s = format (s, ", " #f);
293  _ (syn); _ (ack); _ (fin); _ (rst); _ (psh); _ (urg);
294 #undef _
295 
296  if (tcp->window)
297  s = format (s, ", window 0x%04x", tcp->window);
298  if (tcp->urg)
299  s = format (s, ", urg 0x%04x", tcp->urg_ptr);
300 
301  return s;
302 }
303 
304 u8 * format_udp4_packet (u8 * s, va_list * args)
305 {
306  u8 * p = va_arg (*args, u8 *);
307  struct iphdr * ip = (void *) p;
308  struct udphdr * udp = (void *) (ip + 1);
309 
310  s = format (s, "udp %U:%U -> %U:%U",
311  format_network_address, AF_INET, &ip->saddr,
312  format_network_port, IPPROTO_UDP, ntohs (udp->source),
313  format_network_address, AF_INET, &ip->daddr,
314  format_network_port, IPPROTO_UDP, ntohs (udp->dest));
315 
316  return s;
317 }
318 
319 u8 * format_icmp4_type_and_code (u8 * s, va_list * args)
320 {
321  uword icmp_type = va_arg (*args, uword);
322  uword icmp_code = va_arg (*args, uword);
323 
324  switch (icmp_type)
325  {
326 #define _(f,str) case ICMP_##f: s = format (s, str); break;
327  _ (ECHOREPLY, "echo reply");
328  _ (DEST_UNREACH, "unreachable");
329  _ (SOURCE_QUENCH, "source quench");
330  _ (REDIRECT, "redirect");
331  _ (ECHO, "echo request");
332  _ (TIME_EXCEEDED, "time exceeded");
333  _ (PARAMETERPROB, "parameter problem");
334  _ (TIMESTAMP, "timestamp request");
335  _ (TIMESTAMPREPLY, "timestamp reply");
336  _ (INFO_REQUEST, "information request");
337  _ (INFO_REPLY, "information reply");
338  _ (ADDRESS, "address mask request");
339  _ (ADDRESSREPLY, "address mask reply");
340 #undef _
341  default:
342  s = format (s, "unknown type 0x%x", icmp_type);
343  }
344 
345  if (icmp_type == ICMP_DEST_UNREACH)
346  {
347  switch (icmp_code)
348  {
349 #define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
350  _ (NET_UNREACH, "network");
351  _ (HOST_UNREACH, "host");
352  _ (PROT_UNREACH, "protocol");
353  _ (PORT_UNREACH, "port");
354  _ (FRAG_NEEDED, ": fragmentation needed/DF set");
355  _ (SR_FAILED, "source route failed");
356  _ (NET_UNKNOWN, "network unknown");
357  _ (HOST_UNKNOWN, "host unknown");
358  _ (HOST_ISOLATED, "host isolated");
359  _ (NET_ANO, "network: admin. prohibited");
360  _ (HOST_ANO, "host: admin. prohibited");
361  _ (NET_UNR_TOS, "network for type-of-service");
362  _ (HOST_UNR_TOS, "host for type-of-service");
363  _ (PKT_FILTERED, ": packet filtered");
364  _ (PREC_VIOLATION, "precedence violation");
365  _ (PREC_CUTOFF, "precedence cut off");
366 #undef _
367  default:
368  s = format (s, "unknown code 0x%x", icmp_code);
369  }
370  }
371  else if (icmp_type == ICMP_REDIRECT)
372  {
373  switch (icmp_code)
374  {
375 #define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
376  _ (REDIR_NET, "network");
377  _ (REDIR_HOST, "host");
378  _ (REDIR_NETTOS, "network for type-of-service");
379  _ (REDIR_HOSTTOS, "host for type-of-service");
380 #undef _
381  default:
382  s = format (s, "unknown code 0x%x", icmp_code);
383  }
384  }
385  else if (icmp_type == ICMP_TIME_EXCEEDED)
386  {
387  switch (icmp_code)
388  {
389 #define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
390  _ (EXC_TTL, "time-to-live zero in transit");
391  _ (EXC_FRAGTIME, "time-to-live zero during reassembly");
392 #undef _
393  default:
394  s = format (s, "unknown code 0x%x", icmp_code);
395  }
396  }
397 
398  return s;
399 }
400 
401 typedef struct {
405 } icmp4_t;
406 
407 u8 * format_icmp4_packet (u8 * s, va_list * args)
408 {
409  u8 * p = va_arg (*args, u8 *);
410  struct iphdr * ip = (void *) p;
411  icmp4_t * icmp = (void *) (ip + 1);
412  s = format (s, "icmp %U %U -> %U",
413  format_icmp4_type_and_code, icmp->type, icmp->code,
414  format_network_address, AF_INET, &ip->saddr,
415  format_network_address, AF_INET, &ip->daddr);
416 
417  return s;
418 }
419 
420 u8 * format_ip4_tos_byte (u8 * s, va_list * args)
421 {
422  uword tos = va_arg (*args, uword);
423 
424  if (tos & IPTOS_LOWDELAY)
425  s = format (s, "minimize-delay, ");
426  if (tos & IPTOS_MINCOST)
427  s = format (s, "minimize-cost, ");
428  if (tos & IPTOS_THROUGHPUT)
429  s = format (s, "maximize-throughput, ");
430  if (tos & IPTOS_RELIABILITY)
431  s = format (s, "maximize-reliability, ");
432 
433  switch (IPTOS_PREC (tos))
434  {
435 #define _(x,y) case IPTOS_PREC_##x: s = format (s, y); break
436  _ (NETCONTROL, "network");
437  _ (INTERNETCONTROL, "internet");
438  _ (CRITIC_ECP, "critical");
439  _ (FLASH, "flash");
440  _ (FLASHOVERRIDE, "flash-override");
441  _ (IMMEDIATE, "immediate");
442  _ (PRIORITY, "priority");
443  _ (ROUTINE, "routine");
444 #undef _
445  }
446 
447  return s;
448 }
449 
450 u8 * format_ip4_packet (u8 * s, va_list * args)
451 {
452  u8 * p = va_arg (*args, u8 *);
453  struct iphdr * ip = (void *) p;
454 
455  static format_function_t * f[256];
456 
457  if (! f[IPPROTO_TCP])
458  {
459  f[IPPROTO_TCP] = format_tcp4_packet;
460  f[IPPROTO_UDP] = format_udp4_packet;
461  f[IPPROTO_ICMP] = format_icmp4_packet;
462  }
463 
464  if (f[ip->protocol])
465  return format (s, "%U", f[ip->protocol], p);
466 
467  s = format (s, "%U: %U -> %U",
468  format_network_protocol, AF_INET, ip->protocol,
469  format_network_address, AF_INET, &ip->saddr,
470  format_network_address, AF_INET, &ip->daddr);
471 
472  return s;
473 }
474 
475 #define foreach_unix_arphrd_type \
476  _ (NETROM, 0) \
477  _ (ETHER, 1) \
478  _ (EETHER, 2) \
479  _ (AX25, 3) \
480  _ (PRONET, 4) \
481  _ (CHAOS, 5) \
482  _ (IEEE802, 6) \
483  _ (ARCNET, 7) \
484  _ (APPLETLK, 8) \
485  _ (DLCI, 15) \
486  _ (ATM, 19) \
487  _ (METRICOM, 23) \
488  _ (IEEE1394, 24) \
489  _ (EUI64, 27) \
490  _ (INFINIBAND, 32) \
491  _ (SLIP, 256) \
492  _ (CSLIP, 257) \
493  _ (SLIP6, 258) \
494  _ (CSLIP6, 259) \
495  _ (RSRVD, 260) \
496  _ (ADAPT, 264) \
497  _ (ROSE, 270) \
498  _ (X25, 271) \
499  _ (HWX25, 272) \
500  _ (PPP, 512) \
501  _ (HDLC, 513) \
502  _ (LAPB, 516) \
503  _ (DDCMP, 517) \
504  _ (RAWHDLC, 518) \
505  _ (TUNNEL, 768) \
506  _ (TUNNEL6, 769) \
507  _ (FRAD, 770) \
508  _ (SKIP, 771) \
509  _ (LOOPBACK, 772) \
510  _ (LOCALTLK, 773) \
511  _ (FDDI, 774) \
512  _ (BIF, 775) \
513  _ (SIT, 776) \
514  _ (IPDDP, 777) \
515  _ (IPGRE, 778) \
516  _ (PIMREG, 779) \
517  _ (HIPPI, 780) \
518  _ (ASH, 781) \
519  _ (ECONET, 782) \
520  _ (IRDA, 783) \
521  _ (FCPP, 784) \
522  _ (FCAL, 785) \
523  _ (FCPL, 786) \
524  _ (FCFABRIC, 787) \
525  _ (IEEE802_TR, 800) \
526  _ (IEEE80211, 801) \
527  _ (IEEE80211_PRISM, 802) \
528  _ (IEEE80211_RADIOTAP, 803) \
529  _ (VOID, 0xFFFF) \
530  _ (NONE, 0xFFFE)
531 
532 u8 * format_unix_arphrd (u8 * s, va_list * args)
533 {
534 #ifndef __COVERITY__ /* doesn't understand this at all... */
535  u32 x = va_arg (*args, u32);
536  char * t;
537  switch (x)
538  {
539 #define _(f,n) case ARPHRD_##f: t = #f; break;
541 #undef _
542  default:
543  t = 0;
544  break;
545  }
546 
547  if (t)
548  s = format (s, "%s", t);
549  else
550  s = format (s, "unknown 0x%x", x);
551 #endif
552  return s;
553 }
554 
555 #define foreach_unix_interface_flag \
556  _ (up) \
557  _ (broadcast) \
558  _ (debug) \
559  _ (loopback) \
560  _ (pointopoint) \
561  _ (notrailers) \
562  _ (running) \
563  _ (noarp) \
564  _ (promisc) \
565  _ (allmulti) \
566  _ (master) \
567  _ (slave) \
568  _ (multicast) \
569  _ (portsel) \
570  _ (automedia) \
571  _ (dynamic) \
572  _ (lower_up) \
573  _ (dormant) \
574  _ (echo)
575 
576 static char * unix_interface_flag_names[] = {
577 #define _(f) #f,
579 #undef _
580 };
581 
582 u8 * format_unix_interface_flags (u8 * s, va_list * args)
583 {
584  u32 x = va_arg (*args, u32);
585  u32 i;
586 
587  if (x == 0)
588  s = format (s, "none");
589  else foreach_set_bit (i, x, ({
591  s = format (s, "%s", unix_interface_flag_names[i]);
592  else
593  s = format (s, "unknown %d", i);
594  if (x >> (i + 1))
595  s = format (s, ", ");
596  }));
597  return s;
598 }
599 
600 typedef struct {
601  u16 ar_hrd; /* format of hardware address */
602  u16 ar_pro; /* format of protocol address */
603  u8 ar_hln; /* length of hardware address */
604  u8 ar_pln; /* length of protocol address */
605  u16 ar_op; /* ARP opcode (command) */
606  u8 ar_sha[6]; /* sender hardware address */
607  u8 ar_spa[4]; /* sender IP address */
608  u8 ar_tha[6]; /* target hardware address */
609  u8 ar_tpa[4]; /* target IP address */
611 
612 u8 * format_arp_packet (u8 * s, va_list * args)
613 {
614  arp_ether_ip4_t * a = va_arg (*args, arp_ether_ip4_t *);
615  char * op = "unknown";
616 
617  if (a->ar_pro != ETH_P_IP ||
618  a->ar_hrd != ARPHRD_ETHER)
619  return s;
620 
621  switch (a->ar_op)
622  {
623 #define _(f) case ARPOP_##f: op = #f; break;
624  _ (REQUEST);
625  _ (REPLY);
626  _ (RREQUEST);
627  _ (RREPLY);
628 #undef _
629  }
630 
631  s = format (s, "%s %U %U -> %U %U",
632  op,
633  format_network_address, AF_INET, a->ar_spa,
634  format_network_address, AF_UNSPEC, a->ar_sha,
635  format_network_address, AF_INET, a->ar_tpa,
636  format_network_address, AF_UNSPEC, a->ar_tha);
637  return s;
638 }
639 
640 u8 * format_ethernet_proto (u8 * s, va_list * args)
641 {
642  uword type = va_arg (*args, uword);
643  char * t = 0;
644 
645  switch (type)
646  {
647  case 0: t = "BPDU"; break;
648 #define _(f) case ETH_P_##f: t = #f; break;
649  _ (LOOP);
650  _ (PUP);
651 #ifdef ETH_P_PUPAT
652  _ (PUPAT);
653 #endif
654  _ (IP);
655  _ (X25);
656  _ (ARP);
657  _ (BPQ);
658 #ifdef ETH_P_PUPAT
659  _ (IEEEPUP);
660  _ (IEEEPUPAT);
661 #endif
662  _ (DEC);
663  _ (DNA_DL);
664  _ (DNA_RC);
665  _ (DNA_RT);
666  _ (LAT);
667  _ (DIAG);
668  _ (CUST);
669  _ (SCA);
670  _ (RARP);
671  _ (ATALK);
672  _ (AARP);
673  _ (IPX);
674  _ (IPV6);
675 #ifdef ETH_P_PPP_DISC
676  _ (PPP_DISC);
677  _ (PPP_SES);
678 #endif
679 #ifdef ETH_P_ATMMPOA
680  _ (ATMMPOA);
681  _ (ATMFATE);
682 #endif
683  _ (802_3);
684  _ (AX25);
685  _ (ALL);
686  _ (802_2);
687  _ (SNAP);
688  _ (DDCMP);
689  _ (WAN_PPP);
690  _ (PPP_MP);
691  _ (LOCALTALK);
692  _ (PPPTALK);
693  _ (TR_802_2);
694  _ (MOBITEX);
695  _ (CONTROL);
696  _ (IRDA);
697 #ifdef ETH_P_ECONET
698  _ (ECONET);
699 #endif
700 #undef _
701  }
702 
703  if (t)
704  vec_add (s, t, strlen (t));
705  else
706  s = format (s, "ether-type 0x%x", type);
707  return s;
708 }
709 
710 u8 * format_ethernet_packet (u8 * s, va_list * args)
711 {
712  struct ethhdr * h = va_arg (*args, struct ethhdr *);
713  uword proto = h->h_proto;
714  u8 * payload = (void *) (h + 1);
715  u32 indent;
716 
717  /* Check for 802.2/802.3 encapsulation. */
718  if (proto < ETH_DATA_LEN)
719  {
720  typedef struct {
721  u8 dsap, ssap, control;
722  u8 orig_code[3];
723  u16 proto;
724  } ethhdr_802_t;
725  ethhdr_802_t * h1 = (void *) (h + 1);
726  proto = h1->proto;
727  payload = (void *) (h1 + 1);
728  }
729 
730  indent = format_get_indent (s);
731 
732  s = format (s, "%U: %U -> %U",
733  format_ethernet_proto, proto,
734  format_network_address, AF_UNSPEC, h->h_source,
735  format_network_address, AF_UNSPEC, h->h_dest);
736 
737  switch (proto)
738  {
739  case ETH_P_ARP:
740  s = format (s, "\n%U%U",
741  format_white_space, indent,
742  format_arp_packet, payload);
743  break;
744  }
745 
746  return s;
747 }
748 
749 #ifndef __KERNEL__
750 u8 * format_hostname (u8 * s, va_list * args)
751 {
752  char buffer[1024];
753  char * b = buffer;
754  if (gethostname (b, sizeof (buffer)) < 0)
755  b = "noname";
756  return format (s, "%s", b);
757 }
758 #endif
759 
760 #ifndef __KERNEL__
761 u8 * format_timeval (u8 * s, va_list * args)
762 {
763  char * fmt = va_arg (*args, char *);
764  struct timeval * tv = va_arg (*args, struct timeval *);
765  struct tm * tm;
766  word msec;
767  char * f, c;
768 
769  if (! fmt)
770  fmt = "y/m/d H:M:S:F";
771 
772  if (! tv)
773  {
774  static struct timeval now;
775  gettimeofday (&now, 0);
776  tv = &now;
777  }
778 
779  msec = flt_round_nearest (1e-3 * tv->tv_usec);
780  if (msec >= 1000)
781  { msec = 0; tv->tv_sec++; }
782 
783  {
784  time_t t = tv->tv_sec;
785  tm = localtime (&t);
786  }
787 
788  for (f = fmt; *f; f++)
789  {
790  uword what;
791  char * what_fmt = "%d";
792 
793  switch (c = *f)
794  {
795  default:
796  vec_add1 (s, c);
797  continue;
798 
799  case 'y':
800  what = 1900 + tm->tm_year;
801  what_fmt = "%4d";
802  break;
803  case 'm':
804  what = tm->tm_mon + 1;
805  what_fmt = "%2d";
806  break;
807  case 'd':
808  what = tm->tm_mday;
809  what_fmt = "%2d";
810  break;
811  case 'H':
812  what = tm->tm_hour;
813  what_fmt = "%02d";
814  break;
815  case 'M':
816  what = tm->tm_min;
817  what_fmt = "%02d";
818  break;
819  case 'S':
820  what = tm->tm_sec;
821  what_fmt = "%02d";
822  break;
823  case 'F':
824  what = msec;
825  what_fmt = "%03d";
826  break;
827  }
828 
829  s = format (s, what_fmt, what);
830  }
831 
832  return s;
833 }
834 
835 u8 * format_time_float (u8 * s, va_list * args)
836 {
837  u8 * fmt = va_arg (*args, u8 *);
838  f64 t = va_arg (*args, f64);
839  struct timeval tv;
840  if (t <= 0)
841  t = unix_time_now ();
842  tv.tv_sec = t;
843  tv.tv_usec = 1e6*(t - tv.tv_sec);
844  return format (s, "%U", format_timeval, fmt, &tv);
845 }
846 
847 u8 * format_signal (u8 * s, va_list * args)
848 {
849  uword signum = va_arg (*args, uword);
850  char * t = 0;
851  switch (signum)
852  {
853 #define _(x) case x: t = #x; break;
854  _ (SIGHUP);
855  _ (SIGINT);
856  _ (SIGQUIT);
857  _ (SIGILL);
858  _ (SIGTRAP);
859  _ (SIGABRT);
860  _ (SIGBUS);
861  _ (SIGFPE);
862  _ (SIGKILL);
863  _ (SIGUSR1);
864  _ (SIGSEGV);
865  _ (SIGUSR2);
866  _ (SIGPIPE);
867  _ (SIGALRM);
868  _ (SIGTERM);
869 #ifdef SIGSTKFLT
870  _ (SIGSTKFLT);
871 #endif
872  _ (SIGCHLD);
873  _ (SIGCONT);
874  _ (SIGSTOP);
875  _ (SIGTSTP);
876  _ (SIGTTIN);
877  _ (SIGTTOU);
878  _ (SIGURG);
879  _ (SIGXCPU);
880  _ (SIGXFSZ);
881  _ (SIGVTALRM);
882  _ (SIGPROF);
883  _ (SIGWINCH);
884  _ (SIGIO);
885  _ (SIGPWR);
886 #ifdef SIGSYS
887  _ (SIGSYS);
888 #endif
889 #undef _
890  default:
891  return format (s, "unknown %d", signum);
892  }
893 
894  vec_add (s, t, strlen (t));
895  return s;
896 }
897 
898 u8 * format_ucontext_pc (u8 * s, va_list * args)
899 {
900  ucontext_t * uc __attribute__((unused));
901  unsigned long * regs = 0;
902  uword reg_no = 0;
903 
904  uc = va_arg (*args, ucontext_t *);
905 
906 #if defined (powerpc)
907  regs = &uc->uc_mcontext.uc_regs->gregs[0];
908 #elif defined (powerpc64)
909  regs = &uc->uc_mcontext.uc_regs->gp_regs[0];
910 #elif defined (i386) || defined (__x86_64__)
911  regs = (void *) &uc->uc_mcontext.gregs[0];
912 #endif
913 
914 #if defined (powerpc) || defined (powerpc64)
915  reg_no = PT_NIP;
916 #elif defined (i386)
917  reg_no = REG_EIP;
918 #elif defined (__x86_64__)
919  reg_no = REG_RIP;
920 #else
921  reg_no = 0;
922  regs = 0;
923 #endif
924 
925  if (! regs)
926  return format (s, "unsupported");
927  else
928  return format (s, "%p", regs[reg_no]);
929 }
930 
931 uword
932 unformat_unix_gid (unformat_input_t * input, va_list * args)
933 {
934  gid_t *gid = va_arg (*args, gid_t *);
935  struct group *grp = 0;
936  int r;
937  u8 *s;
938 
939  if (unformat (input, "%d", &r))
940  {
941  grp = getgrgid (r);
942  }
943  else if (unformat (input, "%s", &s))
944  {
945  grp = getgrnam ((char *) s);
946  vec_free (s);
947  }
948  if (grp)
949  {
950  *gid = grp->gr_gid;
951  return 1;
952  }
953  return 0;
954 }
955 
956 #endif /* __KERNEL__ */
u8 * format_arp_packet(u8 *s, va_list *args)
Definition: unix-formats.c:612
u8 * format_time_float(u8 *s, va_list *args)
Definition: unix-formats.c:835
a
Definition: bitmap.h:516
#define clib_error(format, args...)
Definition: error.h:62
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:520
#define foreach_unix_interface_flag
Definition: unix-formats.c:555
int i
u8 * format_ip4_tos_byte(u8 *s, va_list *args)
Definition: unix-formats.c:420
u8 * format_icmp4_type_and_code(u8 *s, va_list *args)
Definition: unix-formats.c:319
u8 * format_ip4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:450
static u32 format_get_indent(u8 *s)
Definition: format.h:72
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define foreach_unix_arphrd_type
Definition: unix-formats.c:475
u8 *( format_function_t)(u8 *s, va_list *args)
Definition: format.h:48
u8 * format_udp4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:304
#define foreach_set_bit(var, mask, body)
Definition: bitops.h:158
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:597
u8 * format_timeval(u8 *s, va_list *args)
Definition: unix-formats.c:761
uword unformat_unix_gid(unformat_input_t *input, va_list *args)
Definition: unix-formats.c:932
u8 * format_address_family(u8 *s, va_list *va)
Definition: unix-formats.c:93
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
static f64 unix_time_now(void)
Definition: time.h:225
#define v
Definition: acl.c:495
struct _unformat_input_t unformat_input_t
u8 * format_unix_interface_flags(u8 *s, va_list *args)
Definition: unix-formats.c:582
u8 * format_unix_arphrd(u8 *s, va_list *args)
Definition: unix-formats.c:532
u8 * format_network_port(u8 *s, va_list *args)
Definition: unix-formats.c:187
u8 * format_icmp4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:407
u8 * format_sockaddr(u8 *s, va_list *args)
Definition: unix-formats.c:230
svmdb_client_t * c
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
static char * unix_interface_flag_names[]
Definition: unix-formats.c:576
#define ARRAY_LEN(x)
Definition: clib.h:59
u16 checksum
Definition: unix-formats.c:404
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u8 * format_network_protocol(u8 *s, va_list *args)
Definition: unix-formats.c:169
u64 uword
Definition: types.h:112
u8 * format_tcp4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:279
unsigned short u16
Definition: types.h:57
i64 word
Definition: types.h:111
static word flt_round_nearest(f64 x)
Definition: clib.h:322
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
u8 * format_ethernet_proto(u8 *s, va_list *args)
Definition: unix-formats.c:640
u8 * format_signal(u8 *s, va_list *args)
Definition: unix-formats.c:847
u8 * format_network_address(u8 *s, va_list *args)
Definition: unix-formats.c:206
u8 * format_ethernet_packet(u8 *s, va_list *args)
Definition: unix-formats.c:710
u8 * format_hostname(u8 *s, va_list *args)
Definition: unix-formats.c:750
vhost_vring_addr_t addr
Definition: vhost-user.h:83
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
u8 * format_ucontext_pc(u8 *s, va_list *args)
Definition: unix-formats.c:898