FD.io VPP  v18.07.1-19-g511ce25
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 #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 {
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;
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,
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, ({
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 */
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__ */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
u8 * format_arp_packet(u8 *s, va_list *args)
Definition: unix-formats.c:613
u8 * format_time_float(u8 *s, va_list *args)
Definition: unix-formats.c:836
a
Definition: bitmap.h:538
#define MAX_NUMNODES
Definition: unix-formats.c:957
#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:523
#define foreach_unix_interface_flag
Definition: unix-formats.c:556
int i
u8 * format_ip4_tos_byte(u8 *s, va_list *args)
Definition: unix-formats.c:421
u8 * format_icmp4_type_and_code(u8 *s, va_list *args)
Definition: unix-formats.c:320
u8 * format_ip4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:451
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:476
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:305
vhost_vring_addr_t addr
Definition: vhost_user.h:116
unsigned char u8
Definition: types.h:56
#define foreach_set_bit(var, mask, body)
Definition: bitops.h:166
double f64
Definition: types.h:142
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:600
u8 * format_timeval(u8 *s, va_list *args)
Definition: unix-formats.c:762
uword unformat_unix_gid(unformat_input_t *input, va_list *args)
Definition: unix-formats.c:933
i64 word
Definition: types.h:111
u8 * format_address_family(u8 *s, va_list *va)
Definition: unix-formats.c:94
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
static f64 unix_time_now(void)
Definition: time.h:228
u8 * format_page_map(u8 *s, va_list *args)
Definition: unix-formats.c:959
unsigned int u32
Definition: types.h:88
uword size
#define v
Definition: acl.c:491
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
u8 * format_unix_interface_flags(u8 *s, va_list *args)
Definition: unix-formats.c:583
u8 * format_unix_arphrd(u8 *s, va_list *args)
Definition: unix-formats.c:533
u8 * format_network_port(u8 *s, va_list *args)
Definition: unix-formats.c:188
u8 * format_icmp4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:408
u8 * format_sockaddr(u8 *s, va_list *args)
Definition: unix-formats.c:231
svmdb_client_t * c
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
static char * unix_interface_flag_names[]
Definition: unix-formats.c:577
#define ARRAY_LEN(x)
Definition: clib.h:59
u16 checksum
Definition: unix-formats.c:405
#define uword_to_pointer(u, type)
Definition: types.h:136
#define ASSERT(truth)
u8 * format_network_protocol(u8 *s, va_list *args)
Definition: unix-formats.c:170
u8 * format_tcp4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:280
static word flt_round_nearest(f64 x)
Definition: clib.h:271
u8 * format_ethernet_proto(u8 *s, va_list *args)
Definition: unix-formats.c:641
u64 uword
Definition: types.h:112
u8 * format_signal(u8 *s, va_list *args)
Definition: unix-formats.c:848
u8 * format_network_address(u8 *s, va_list *args)
Definition: unix-formats.c:207
u8 * format_ethernet_packet(u8 *s, va_list *args)
Definition: unix-formats.c:711
u8 * format_hostname(u8 *s, va_list *args)
Definition: unix-formats.c:751
static long move_pages(int pid, unsigned long count, void **pages, const int *nodes, int *status, int flags)
Definition: syscall.h:36
uword clib_mem_get_page_size(void)
Definition: mem_mheap.c:110
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:899