FD.io VPP  v19.04-6-g6f05f72
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 #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 {
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;
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,
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, ({
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 */
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__ */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
u8 * format_arp_packet(u8 *s, va_list *args)
Definition: unix-formats.c:622
u8 * format_time_float(u8 *s, va_list *args)
Definition: unix-formats.c:846
a
Definition: bitmap.h:538
#define MAX_NUMNODES
Definition: unix-formats.c:967
#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:522
#define foreach_unix_interface_flag
Definition: unix-formats.c:565
int i
u8 * format_ip4_tos_byte(u8 *s, va_list *args)
Definition: unix-formats.c:430
u8 * format_icmp4_type_and_code(u8 *s, va_list *args)
Definition: unix-formats.c:329
u8 * format_ip4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:460
static u32 format_get_indent(u8 *s)
Definition: format.h:72
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define foreach_unix_arphrd_type
Definition: unix-formats.c:485
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:314
vhost_vring_addr_t addr
Definition: vhost_user.h:121
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:598
u8 * format_timeval(u8 *s, va_list *args)
Definition: unix-formats.c:771
uword unformat_unix_gid(unformat_input_t *input, va_list *args)
Definition: unix-formats.c:943
i64 word
Definition: types.h:111
u8 * format_address_family(u8 *s, va_list *va)
Definition: unix-formats.c:102
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
static f64 unix_time_now(void)
Definition: time.h:240
u8 * format_page_map(u8 *s, va_list *args)
Definition: unix-formats.c:969
unsigned int u32
Definition: types.h:88
uword size
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
uword clib_mem_get_page_size(void)
Definition: mem.c:51
u8 * format_unix_interface_flags(u8 *s, va_list *args)
Definition: unix-formats.c:592
u8 * format_unix_arphrd(u8 *s, va_list *args)
Definition: unix-formats.c:542
u8 * format_network_port(u8 *s, va_list *args)
Definition: unix-formats.c:196
u8 * format_icmp4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:417
u8 * format_sockaddr(u8 *s, va_list *args)
Definition: unix-formats.c:239
svmdb_client_t * c
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
static char * unix_interface_flag_names[]
Definition: unix-formats.c:586
#define ARRAY_LEN(x)
Definition: clib.h:62
u16 checksum
Definition: unix-formats.c:414
#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:178
u8 * format_tcp4_packet(u8 *s, va_list *args)
Definition: unix-formats.c:289
static word flt_round_nearest(f64 x)
Definition: clib.h:277
u8 * format_ethernet_proto(u8 *s, va_list *args)
Definition: unix-formats.c:650
u64 uword
Definition: types.h:112
u8 * format_signal(u8 *s, va_list *args)
Definition: unix-formats.c:858
u8 * format_network_address(u8 *s, va_list *args)
Definition: unix-formats.c:215
u8 * format_ethernet_packet(u8 *s, va_list *args)
Definition: unix-formats.c:720
u8 * format_hostname(u8 *s, va_list *args)
Definition: unix-formats.c:760
static long move_pages(int pid, unsigned long count, void **pages, const int *nodes, int *status, int flags)
Definition: syscall.h:44
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
u8 protocol
Definition: ipsec.api:96
u8 * format_ucontext_pc(u8 *s, va_list *args)
Definition: unix-formats.c:909