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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
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:
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
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.
40 # include <linux/unistd.h>
41 # include <linux/signal.h>
43 #else /* ! __KERNEL__ */
45 #define _GNU_SOURCE /* to get REG_* in ucontext.h */
55 #include <sys/socket.h>
59 #include <vppinfra/time.h>
60 #include <vppinfra/linux/syscall.h>
63 #include <linux/types.h>
64 #include <linux/netlink.h>
67 #endif /* ! __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>
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__ */
89 #include <vppinfra/bitops.h> /* foreach_set_bit */
90 #include <vppinfra/format.h>
91 #include <vppinfra/error.h>
93 /* Format unix network address family (e.g. AF_INET). */
94 u8 * format_address_family (u8 * s, va_list * va)
96 uword family = va_arg (*va, uword);
97 u8 * t = (u8 *) "UNKNOWN";
100 #define _(x) case PF_##x: t = (u8 *) #x; break
102 _ (UNIX); /* Unix domain sockets */
103 _ (INET); /* Internet IP Protocol */
105 _ (AX25); /* Amateur Radio AX.25 */
108 _ (IPX); /* Novell IPX */
111 _ (APPLETALK); /* AppleTalk DDP */
114 _ (NETROM); /* Amateur Radio NET/ROM */
117 _ (BRIDGE); /* Multiprotocol bridge */
120 _ (ATMPVC); /* ATM PVCs */
123 _ (X25); /* Reserved for X.25 project */
126 _ (INET6); /* IP version 6 */
129 _ (ROSE); /* Amateur Radio X.25 PLP */
132 _ (DECnet); /* Reserved for DECnet project */
135 _ (NETBEUI); /* Reserved for 802.2LLC project*/
138 _ (SECURITY); /* Security callback pseudo AF */
141 _ (KEY); /* PF_KEY key management API */
147 _ (PACKET); /* Packet family */
153 _ (ECONET); /* Acorn Econet */
156 _ (ATMSVC); /* ATM SVCs */
159 _ (SNA); /* Linux SNA Project */
162 _ (IRDA); /* IRDA sockets */
166 vec_add (s, t, strlen ((char *) t));
170 u8 * format_network_protocol (u8 * s, va_list * args)
172 uword family = va_arg (*args, uword);
173 uword protocol = va_arg (*args, uword);
176 struct protoent * p = getprotobynumber (protocol);
178 ASSERT (family == AF_INET);
180 return format (s, "%s", p->p_name);
182 return format (s, "%d", protocol);
184 return format (s, "%d/%d", family, protocol);
188 u8 * format_network_port (u8 * s, va_list * args)
190 uword proto = va_arg (*args, uword);
191 uword port = va_arg (*args, uword);
194 struct servent * p = getservbyport (port, proto == IPPROTO_UDP ? "udp" : "tcp");
197 return format (s, "%s", p->s_name);
199 return format (s, "%d", port);
201 return format (s, "%s/%d", proto == IPPROTO_UDP ? "udp" : "tcp", port);
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)
209 uword family = va_arg (*args, uword);
210 u8 * addr = va_arg (*args, u8 *);
215 s = format (s, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
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]);
225 clib_error ("unsupported address family %d", family);
231 u8 * format_sockaddr (u8 * s, va_list * args)
233 void * v = va_arg (*args, void *);
234 struct sockaddr * sa = v;
235 static u32 local_counter;
237 switch (sa->sa_family)
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));
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.
255 s = format (s, "local:%u", local_counter++);
263 struct sockaddr_nl * n = v;
264 s = format (s, "KERNEL-NETLINK");
266 s = format (s, " (groups 0x%x)", n->nl_groups);
273 s = format (s, "sockaddr family %d", sa->sa_family);
280 u8 * format_tcp4_packet (u8 * s, va_list * args)
282 u8 * p = va_arg (*args, u8 *);
283 struct iphdr * ip = (void *) p;
284 struct tcphdr * tcp = (void *) (ip + 1);
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));
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);
298 s = format (s, ", window 0x%04x", tcp->window);
300 s = format (s, ", urg 0x%04x", tcp->urg_ptr);
305 u8 * format_udp4_packet (u8 * s, va_list * args)
307 u8 * p = va_arg (*args, u8 *);
308 struct iphdr * ip = (void *) p;
309 struct udphdr * udp = (void *) (ip + 1);
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));
320 u8 * format_icmp4_type_and_code (u8 * s, va_list * args)
322 uword icmp_type = va_arg (*args, uword);
323 uword icmp_code = va_arg (*args, uword);
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");
343 s = format (s, "unknown type 0x%x", icmp_type);
346 if (icmp_type == ICMP_DEST_UNREACH)
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");
369 s = format (s, "unknown code 0x%x", icmp_code);
372 else if (icmp_type == ICMP_REDIRECT)
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");
383 s = format (s, "unknown code 0x%x", icmp_code);
386 else if (icmp_type == ICMP_TIME_EXCEEDED)
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");
395 s = format (s, "unknown code 0x%x", icmp_code);
408 u8 * format_icmp4_packet (u8 * s, va_list * args)
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);
421 u8 * format_ip4_tos_byte (u8 * s, va_list * args)
423 uword tos = va_arg (*args, uword);
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, ");
434 switch (IPTOS_PREC (tos))
436 #define _(x,y) case IPTOS_PREC_##x: s = format (s, y); break
437 _ (NETCONTROL, "network");
438 _ (INTERNETCONTROL, "internet");
439 _ (CRITIC_ECP, "critical");
441 _ (FLASHOVERRIDE, "flash-override");
442 _ (IMMEDIATE, "immediate");
443 _ (PRIORITY, "priority");
444 _ (ROUTINE, "routine");
451 u8 * format_ip4_packet (u8 * s, va_list * args)
453 u8 * p = va_arg (*args, u8 *);
454 struct iphdr * ip = (void *) p;
456 static format_function_t * f[256];
458 if (! f[IPPROTO_TCP])
460 f[IPPROTO_TCP] = format_tcp4_packet;
461 f[IPPROTO_UDP] = format_udp4_packet;
462 f[IPPROTO_ICMP] = format_icmp4_packet;
466 return format (s, "%U", f[ip->protocol], p);
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);
476 #define foreach_unix_arphrd_type \
526 _ (IEEE802_TR, 800) \
528 _ (IEEE80211_PRISM, 802) \
529 _ (IEEE80211_RADIOTAP, 803) \
533 u8 * format_unix_arphrd (u8 * s, va_list * args)
535 #ifndef __COVERITY__ /* doesn't understand this at all... */
536 u32 x = va_arg (*args, u32);
540 #define _(f,n) case ARPHRD_##f: t = #f; break;
541 foreach_unix_arphrd_type
549 s = format (s, "%s", t);
551 s = format (s, "unknown 0x%x", x);
556 #define foreach_unix_interface_flag \
577 static char * unix_interface_flag_names[] = {
579 foreach_unix_interface_flag
583 u8 * format_unix_interface_flags (u8 * s, va_list * args)
585 u32 x = va_arg (*args, u32);
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]);
594 s = format (s, "unknown %d", i);
596 s = format (s, ", ");
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 */
613 u8 * format_arp_packet (u8 * s, va_list * args)
615 arp_ether_ip4_t * a = va_arg (*args, arp_ether_ip4_t *);
616 char * op = "unknown";
618 if (a->ar_pro != ETH_P_IP ||
619 a->ar_hrd != ARPHRD_ETHER)
624 #define _(f) case ARPOP_##f: op = #f; break;
632 s = format (s, "%s %U %U -> %U %U",
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);
641 u8 * format_ethernet_proto (u8 * s, va_list * args)
643 uword type = va_arg (*args, uword);
648 case 0: t = "BPDU"; break;
649 #define _(f) case ETH_P_##f: t = #f; break;
676 #ifdef ETH_P_PPP_DISC
705 vec_add (s, t, strlen (t));
707 s = format (s, "ether-type 0x%x", type);
711 u8 * format_ethernet_packet (u8 * s, va_list * args)
713 struct ethhdr * h = va_arg (*args, struct ethhdr *);
714 uword proto = h->h_proto;
715 u8 * payload = (void *) (h + 1);
718 /* Check for 802.2/802.3 encapsulation. */
719 if (proto < ETH_DATA_LEN)
722 u8 dsap, ssap, control;
726 ethhdr_802_t * h1 = (void *) (h + 1);
728 payload = (void *) (h1 + 1);
731 indent = format_get_indent (s);
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);
741 s = format (s, "\n%U%U",
742 format_white_space, indent,
743 format_arp_packet, payload);
751 u8 * format_hostname (u8 * s, va_list * args)
755 if (gethostname (b, sizeof (buffer)) < 0)
757 return format (s, "%s", b);
762 u8 * format_timeval (u8 * s, va_list * args)
764 char * fmt = va_arg (*args, char *);
765 struct timeval * tv = va_arg (*args, struct timeval *);
771 fmt = "y/m/d H:M:S:F";
775 static struct timeval now;
776 gettimeofday (&now, 0);
780 msec = flt_round_nearest (1e-3 * tv->tv_usec);
782 { msec = 0; tv->tv_sec++; }
785 time_t t = tv->tv_sec;
789 for (f = fmt; *f; f++)
792 char * what_fmt = "%d";
801 what = 1900 + tm->tm_year;
805 what = tm->tm_mon + 1;
830 s = format (s, what_fmt, what);
836 u8 * format_time_float (u8 * s, va_list * args)
838 u8 * fmt = va_arg (*args, u8 *);
839 f64 t = va_arg (*args, f64);
842 t = unix_time_now ();
844 tv.tv_usec = 1e6*(t - tv.tv_sec);
845 return format (s, "%U", format_timeval, fmt, &tv);
848 u8 * format_signal (u8 * s, va_list * args)
850 uword signum = va_arg (*args, uword);
854 #define _(x) case x: t = #x; break;
892 return format (s, "unknown %d", signum);
895 vec_add (s, t, strlen (t));
899 u8 * format_ucontext_pc (u8 * s, va_list * args)
901 ucontext_t * uc __attribute__((unused));
902 unsigned long * regs = 0;
905 uc = va_arg (*args, ucontext_t *);
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];
915 #if defined (powerpc) || defined (powerpc64)
919 #elif defined (__x86_64__)
927 return format (s, "unsupported");
929 return format (s, "%p", regs[reg_no]);
933 unformat_unix_gid (unformat_input_t * input, va_list * args)
935 gid_t *gid = va_arg (*args, gid_t *);
936 struct group *grp = 0;
940 if (unformat (input, "%d", &r))
944 else if (unformat (input, "%s", &s))
946 grp = getgrnam ((char *) s);
957 #define MAX_NUMNODES 16
959 format_page_map (u8 * s, va_list * args)
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;
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);
976 vec_validate (status, n_pages - 1);
977 vec_validate (ptr, n_pages - 1);
979 for (i = 0; i < n_pages; i++)
980 ptr[i] = uword_to_pointer (va + i * page_size, void *);
982 if (move_pages (0, n_pages, ptr, 0, status, 0) != 0)
984 s = format (s, "\n%Upage information not available (errno %u)",
985 format_white_space, indent + 2, errno);
989 for (i = 0; i < n_pages; i++)
991 if (status[i] >= 0 && status[i] < MAX_NUMNODES)
992 pages_per_numa[status[i]]++;
993 else if (status[i] == -EFAULT)
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] *
1005 s = format (s, "\n%Unot mapped: %u pages, %luk", format_white_space,
1006 indent + 2, pages_not_mapped, pages_not_mapped *
1010 s = format (s, "\n%Uunknown: %u pages, %luk", format_white_space,
1011 indent + 2, pages_unknown, pages_unknown * page_size / 1024);
1019 #endif /* __KERNEL__ */