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.
41 # include <linux/unistd.h>
42 # include <linux/signal.h>
45 #else /* ! __KERNEL__ */
51 #define _GNU_SOURCE /* to get REG_* in ucontext.h */
61 #include <sys/socket.h>
65 #include <vppinfra/time.h>
67 #include <vppinfra/linux/syscall.h>
70 #include <linux/types.h>
71 #include <linux/netlink.h>
75 #endif /* ! __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>
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__ */
97 #include <vppinfra/bitops.h> /* foreach_set_bit */
98 #include <vppinfra/format.h>
99 #include <vppinfra/error.h>
101 /* Format unix network address family (e.g. AF_INET). */
102 u8 * format_address_family (u8 * s, va_list * va)
104 uword family = va_arg (*va, uword);
105 u8 * t = (u8 *) "UNKNOWN";
108 #define _(x) case PF_##x: t = (u8 *) #x; break
110 _ (UNIX); /* Unix domain sockets */
111 _ (INET); /* Internet IP Protocol */
113 _ (AX25); /* Amateur Radio AX.25 */
116 _ (IPX); /* Novell IPX */
119 _ (APPLETALK); /* AppleTalk DDP */
122 _ (NETROM); /* Amateur Radio NET/ROM */
125 _ (BRIDGE); /* Multiprotocol bridge */
128 _ (ATMPVC); /* ATM PVCs */
131 _ (X25); /* Reserved for X.25 project */
134 _ (INET6); /* IP version 6 */
137 _ (ROSE); /* Amateur Radio X.25 PLP */
140 _ (DECnet); /* Reserved for DECnet project */
143 _ (NETBEUI); /* Reserved for 802.2LLC project*/
146 _ (SECURITY); /* Security callback pseudo AF */
149 _ (KEY); /* PF_KEY key management API */
155 _ (PACKET); /* Packet family */
161 _ (ECONET); /* Acorn Econet */
164 _ (ATMSVC); /* ATM SVCs */
167 _ (SNA); /* Linux SNA Project */
170 _ (IRDA); /* IRDA sockets */
174 vec_add (s, t, strlen ((char *) t));
178 u8 * format_network_protocol (u8 * s, va_list * args)
180 uword family = va_arg (*args, uword);
181 uword protocol = va_arg (*args, uword);
184 struct protoent * p = getprotobynumber (protocol);
186 ASSERT (family == AF_INET);
188 return format (s, "%s", p->p_name);
190 return format (s, "%d", protocol);
192 return format (s, "%d/%d", family, protocol);
196 u8 * format_network_port (u8 * s, va_list * args)
198 uword proto = va_arg (*args, uword);
199 uword port = va_arg (*args, uword);
202 struct servent * p = getservbyport (port, proto == IPPROTO_UDP ? "udp" : "tcp");
205 return format (s, "%s", p->s_name);
207 return format (s, "%d", port);
209 return format (s, "%s/%d", proto == IPPROTO_UDP ? "udp" : "tcp", port);
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)
217 uword family = va_arg (*args, uword);
218 u8 * addr = va_arg (*args, u8 *);
223 s = format (s, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
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]);
233 clib_error ("unsupported address family %d", family);
239 u8 * format_sockaddr (u8 * s, va_list * args)
241 void * v = va_arg (*args, void *);
242 struct sockaddr * sa = v;
243 static u32 local_counter;
245 switch (sa->sa_family)
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));
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.
263 s = format (s, "local:%u", local_counter++);
271 struct sockaddr_nl * n = v;
272 s = format (s, "KERNEL-NETLINK");
274 s = format (s, " (groups 0x%x)", n->nl_groups);
281 s = format (s, "sockaddr family %d", sa->sa_family);
289 u8 * format_tcp4_packet (u8 * s, va_list * args)
291 u8 * p = va_arg (*args, u8 *);
292 struct iphdr * ip = (void *) p;
293 struct tcphdr * tcp = (void *) (ip + 1);
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));
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);
307 s = format (s, ", window 0x%04x", tcp->window);
309 s = format (s, ", urg 0x%04x", tcp->urg_ptr);
314 u8 * format_udp4_packet (u8 * s, va_list * args)
316 u8 * p = va_arg (*args, u8 *);
317 struct iphdr * ip = (void *) p;
318 struct udphdr * udp = (void *) (ip + 1);
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));
329 u8 * format_icmp4_type_and_code (u8 * s, va_list * args)
331 uword icmp_type = va_arg (*args, uword);
332 uword icmp_code = va_arg (*args, uword);
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");
352 s = format (s, "unknown type 0x%x", icmp_type);
355 if (icmp_type == ICMP_DEST_UNREACH)
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");
378 s = format (s, "unknown code 0x%x", icmp_code);
381 else if (icmp_type == ICMP_REDIRECT)
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");
392 s = format (s, "unknown code 0x%x", icmp_code);
395 else if (icmp_type == ICMP_TIME_EXCEEDED)
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");
404 s = format (s, "unknown code 0x%x", icmp_code);
417 u8 * format_icmp4_packet (u8 * s, va_list * args)
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);
430 u8 * format_ip4_tos_byte (u8 * s, va_list * args)
432 uword tos = va_arg (*args, uword);
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, ");
443 switch (IPTOS_PREC (tos))
445 #define _(x,y) case IPTOS_PREC_##x: s = format (s, y); break
446 _ (NETCONTROL, "network");
447 _ (INTERNETCONTROL, "internet");
448 _ (CRITIC_ECP, "critical");
450 _ (FLASHOVERRIDE, "flash-override");
451 _ (IMMEDIATE, "immediate");
452 _ (PRIORITY, "priority");
453 _ (ROUTINE, "routine");
460 u8 * format_ip4_packet (u8 * s, va_list * args)
462 u8 * p = va_arg (*args, u8 *);
463 struct iphdr * ip = (void *) p;
465 static format_function_t * f[256];
467 if (! f[IPPROTO_TCP])
469 f[IPPROTO_TCP] = format_tcp4_packet;
470 f[IPPROTO_UDP] = format_udp4_packet;
471 f[IPPROTO_ICMP] = format_icmp4_packet;
475 return format (s, "%U", f[ip->protocol], p);
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);
485 #define foreach_unix_arphrd_type \
535 _ (IEEE802_TR, 800) \
537 _ (IEEE80211_PRISM, 802) \
538 _ (IEEE80211_RADIOTAP, 803) \
542 u8 * format_unix_arphrd (u8 * s, va_list * args)
544 #ifndef __COVERITY__ /* doesn't understand this at all... */
545 u32 x = va_arg (*args, u32);
549 #define _(f,n) case ARPHRD_##f: t = #f; break;
550 foreach_unix_arphrd_type
558 s = format (s, "%s", t);
560 s = format (s, "unknown 0x%x", x);
565 #define foreach_unix_interface_flag \
586 static char * unix_interface_flag_names[] = {
588 foreach_unix_interface_flag
592 u8 * format_unix_interface_flags (u8 * s, va_list * args)
594 u32 x = va_arg (*args, u32);
598 s = format (s, "none");
599 else foreach_set_bit (i, x, ({
600 if (i < ARRAY_LEN (unix_interface_flag_names))
601 s = format (s, "%s", unix_interface_flag_names[i]);
603 s = format (s, "unknown %d", i);
605 s = format (s, ", ");
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 */
622 u8 * format_arp_packet (u8 * s, va_list * args)
624 arp_ether_ip4_t * a = va_arg (*args, arp_ether_ip4_t *);
625 char * op = "unknown";
627 if (a->ar_pro != ETH_P_IP ||
628 a->ar_hrd != ARPHRD_ETHER)
633 #define _(f) case ARPOP_##f: op = #f; break;
641 s = format (s, "%s %U %U -> %U %U",
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);
650 u8 * format_ethernet_proto (u8 * s, va_list * args)
652 uword type = va_arg (*args, uword);
657 case 0: t = "BPDU"; break;
658 #define _(f) case ETH_P_##f: t = #f; break;
685 #ifdef ETH_P_PPP_DISC
714 vec_add (s, t, strlen (t));
716 s = format (s, "ether-type 0x%x", type);
720 u8 * format_ethernet_packet (u8 * s, va_list * args)
722 struct ethhdr * h = va_arg (*args, struct ethhdr *);
723 uword proto = h->h_proto;
724 u8 * payload = (void *) (h + 1);
727 /* Check for 802.2/802.3 encapsulation. */
728 if (proto < ETH_DATA_LEN)
731 u8 dsap, ssap, control;
735 ethhdr_802_t * h1 = (void *) (h + 1);
737 payload = (void *) (h1 + 1);
740 indent = format_get_indent (s);
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);
750 s = format (s, "\n%U%U",
751 format_white_space, indent,
752 format_arp_packet, payload);
760 u8 * format_hostname (u8 * s, va_list * args)
764 if (gethostname (b, sizeof (buffer)) < 0)
766 return format (s, "%s", b);
771 u8 * format_timeval (u8 * s, va_list * args)
773 char * fmt = va_arg (*args, char *);
774 struct timeval * tv = va_arg (*args, struct timeval *);
780 fmt = "y/m/d H:M:S:F";
784 static struct timeval now;
785 gettimeofday (&now, 0);
789 msec = flt_round_nearest (1e-3 * tv->tv_usec);
791 { msec = 0; tv->tv_sec++; }
794 time_t t = tv->tv_sec;
798 for (f = fmt; *f; f++)
801 char * what_fmt = "%d";
810 what = 1900 + tm->tm_year;
814 what = tm->tm_mon + 1;
839 s = format (s, what_fmt, what);
846 u8 * format_time_float (u8 * s, va_list * args)
848 u8 * fmt = va_arg (*args, u8 *);
849 f64 t = va_arg (*args, f64);
852 t = unix_time_now ();
854 tv.tv_usec = 1e6*(t - tv.tv_sec);
855 return format (s, "%U", format_timeval, fmt, &tv);
858 u8 * format_signal (u8 * s, va_list * args)
860 uword signum = va_arg (*args, uword);
864 #define _(x) case x: t = #x; break;
902 return format (s, "unknown %d", signum);
905 vec_add (s, t, strlen (t));
909 u8 * format_ucontext_pc (u8 * s, va_list * args)
911 ucontext_t * uc __attribute__((unused));
912 unsigned long * regs = 0;
915 uc = va_arg (*args, ucontext_t *);
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];
925 #if defined (powerpc) || defined (powerpc64)
929 #elif defined (__x86_64__)
937 return format (s, "unsupported");
939 return format (s, "%p", regs[reg_no]);
943 unformat_unix_gid (unformat_input_t * input, va_list * args)
945 gid_t *gid = va_arg (*args, gid_t *);
946 struct group *grp = 0;
950 if (unformat (input, "%d", &r))
954 else if (unformat (input, "%s", &s))
956 grp = getgrnam ((char *) s);
967 #endif /* __KERNEL__ */