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 */
60 #include <sys/socket.h>
64 #include <vppinfra/time.h>
66 #include <vppinfra/linux/syscall.h>
69 #include <linux/types.h>
70 #include <linux/netlink.h>
74 #endif /* ! __KERNEL__ */
78 # include <linux/socket.h>
79 # include <linux/in.h>
80 # include <linux/ip.h>
81 # include <linux/tcp.h>
82 # include <linux/udp.h>
83 # include <linux/icmp.h>
84 # include <linux/if_ether.h>
85 # include <linux/if_arp.h>
87 # include <net/if.h> /* struct ifnet may live here */
88 # include <netinet/in.h>
89 # include <netinet/ip.h>
90 # include <netinet/tcp.h>
91 # include <netinet/udp.h>
92 # include <netinet/ip_icmp.h>
93 # include <netinet/if_ether.h>
94 #endif /* __KERNEL__ */
96 #include <vppinfra/bitops.h> /* foreach_set_bit */
97 #include <vppinfra/format.h>
98 #include <vppinfra/error.h>
100 /* Format unix network address family (e.g. AF_INET). */
101 u8 * format_address_family (u8 * s, va_list * va)
103 uword family = va_arg (*va, uword);
104 u8 * t = (u8 *) "UNKNOWN";
107 #define _(x) case PF_##x: t = (u8 *) #x; break
109 _ (UNIX); /* Unix domain sockets */
110 _ (INET); /* Internet IP Protocol */
112 _ (AX25); /* Amateur Radio AX.25 */
115 _ (IPX); /* Novell IPX */
118 _ (APPLETALK); /* AppleTalk DDP */
121 _ (NETROM); /* Amateur Radio NET/ROM */
124 _ (BRIDGE); /* Multiprotocol bridge */
127 _ (ATMPVC); /* ATM PVCs */
130 _ (X25); /* Reserved for X.25 project */
133 _ (INET6); /* IP version 6 */
136 _ (ROSE); /* Amateur Radio X.25 PLP */
139 _ (DECnet); /* Reserved for DECnet project */
142 _ (NETBEUI); /* Reserved for 802.2LLC project*/
145 _ (SECURITY); /* Security callback pseudo AF */
148 _ (KEY); /* PF_KEY key management API */
154 _ (PACKET); /* Packet family */
160 _ (ECONET); /* Acorn Econet */
163 _ (ATMSVC); /* ATM SVCs */
166 _ (SNA); /* Linux SNA Project */
169 _ (IRDA); /* IRDA sockets */
173 vec_add (s, t, strlen ((char *) t));
177 u8 * format_network_protocol (u8 * s, va_list * args)
179 uword family = va_arg (*args, uword);
180 uword protocol = va_arg (*args, uword);
183 struct protoent * p = getprotobynumber (protocol);
185 ASSERT (family == AF_INET);
187 return format (s, "%s", p->p_name);
189 return format (s, "%d", protocol);
191 return format (s, "%d/%d", family, protocol);
195 u8 * format_network_port (u8 * s, va_list * args)
197 uword proto = va_arg (*args, uword);
198 uword port = va_arg (*args, uword);
201 struct servent * p = getservbyport (port, proto == IPPROTO_UDP ? "udp" : "tcp");
204 return format (s, "%s", p->s_name);
206 return format (s, "%d", port);
208 return format (s, "%s/%d", proto == IPPROTO_UDP ? "udp" : "tcp", port);
212 /* Format generic network address: takes two arguments family and address.
213 Assumes network byte order. */
214 u8 * format_network_address (u8 * s, va_list * args)
216 uword family = va_arg (*args, uword);
217 u8 * addr = va_arg (*args, u8 *);
222 s = format (s, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
226 /* We use AF_UNSPEC for ethernet addresses. */
227 s = format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
228 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
232 clib_error ("unsupported address family %d", family);
238 u8 * format_sockaddr (u8 * s, va_list * args)
240 void * v = va_arg (*args, void *);
241 struct sockaddr * sa = v;
242 static u32 local_counter;
244 switch (sa->sa_family)
248 struct sockaddr_in * i = v;
249 s = format (s, "%U:%U",
250 format_network_address, AF_INET, &i->sin_addr.s_addr,
251 format_network_port, IPPROTO_TCP, ntohs (i->sin_port));
258 * There isn't anything useful to print.
259 * The unix cli world uses the output to make a node name,
260 * so we need to return a unique name.
262 s = format (s, "local:%u", local_counter++);
270 struct sockaddr_nl * n = v;
271 s = format (s, "KERNEL-NETLINK");
273 s = format (s, " (groups 0x%x)", n->nl_groups);
280 s = format (s, "sockaddr family %d", sa->sa_family);
288 u8 * format_tcp4_packet (u8 * s, va_list * args)
290 u8 * p = va_arg (*args, u8 *);
291 struct iphdr * ip = (void *) p;
292 struct tcphdr * tcp = (void *) (ip + 1);
294 s = format (s, "tcp %U:%U -> %U:%U",
295 format_network_address, AF_INET, &ip->saddr,
296 format_network_port, IPPROTO_TCP, ntohs (tcp->source),
297 format_network_address, AF_INET, &ip->daddr,
298 format_network_port, IPPROTO_TCP, ntohs (tcp->dest));
300 s = format (s, ", seq 0x%08x -> 0x%08x", tcp->seq, tcp->ack_seq);
301 #define _(f) if (tcp->f) s = format (s, ", " #f);
302 _ (syn); _ (ack); _ (fin); _ (rst); _ (psh); _ (urg);
306 s = format (s, ", window 0x%04x", tcp->window);
308 s = format (s, ", urg 0x%04x", tcp->urg_ptr);
313 u8 * format_udp4_packet (u8 * s, va_list * args)
315 u8 * p = va_arg (*args, u8 *);
316 struct iphdr * ip = (void *) p;
317 struct udphdr * udp = (void *) (ip + 1);
319 u16 source = udp->uh_sport;
320 u16 dest = udp->uh_dport;
322 s = format (s, "udp %U:%U -> %U:%U", format_network_address, AF_INET,
323 &ip->saddr, format_network_port, IPPROTO_UDP, ntohs (source),
324 format_network_address, AF_INET, &ip->daddr, format_network_port,
325 IPPROTO_UDP, ntohs (dest));
330 u8 * format_icmp4_type_and_code (u8 * s, va_list * args)
332 uword icmp_type = va_arg (*args, uword);
333 uword icmp_code = va_arg (*args, uword);
337 #define _(f,str) case ICMP_##f: s = format (s, str); break;
338 _ (ECHOREPLY, "echo reply");
339 _ (DEST_UNREACH, "unreachable");
340 _ (SOURCE_QUENCH, "source quench");
341 _ (REDIRECT, "redirect");
342 _ (ECHO, "echo request");
343 _ (TIME_EXCEEDED, "time exceeded");
344 _ (PARAMETERPROB, "parameter problem");
345 _ (TIMESTAMP, "timestamp request");
346 _ (TIMESTAMPREPLY, "timestamp reply");
347 _ (INFO_REQUEST, "information request");
348 _ (INFO_REPLY, "information reply");
349 _ (ADDRESS, "address mask request");
350 _ (ADDRESSREPLY, "address mask reply");
353 s = format (s, "unknown type 0x%x", icmp_type);
356 if (icmp_type == ICMP_DEST_UNREACH)
360 #define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
361 _ (NET_UNREACH, "network");
362 _ (HOST_UNREACH, "host");
363 _ (PROT_UNREACH, "protocol");
364 _ (PORT_UNREACH, "port");
365 _ (FRAG_NEEDED, ": fragmentation needed/DF set");
366 _ (SR_FAILED, "source route failed");
367 _ (NET_UNKNOWN, "network unknown");
368 _ (HOST_UNKNOWN, "host unknown");
369 _ (HOST_ISOLATED, "host isolated");
370 _ (NET_ANO, "network: admin. prohibited");
371 _ (HOST_ANO, "host: admin. prohibited");
372 _ (NET_UNR_TOS, "network for type-of-service");
373 _ (HOST_UNR_TOS, "host for type-of-service");
374 _ (PKT_FILTERED, ": packet filtered");
375 _ (PREC_VIOLATION, "precedence violation");
376 _ (PREC_CUTOFF, "precedence cut off");
379 s = format (s, "unknown code 0x%x", icmp_code);
382 else if (icmp_type == ICMP_REDIRECT)
386 #define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
387 _ (REDIR_NET, "network");
388 _ (REDIR_HOST, "host");
389 _ (REDIR_NETTOS, "network for type-of-service");
390 _ (REDIR_HOSTTOS, "host for type-of-service");
393 s = format (s, "unknown code 0x%x", icmp_code);
396 else if (icmp_type == ICMP_TIME_EXCEEDED)
400 #define _(f,str) case ICMP_##f: s = format (s, " " # str); break;
401 _ (EXC_TTL, "time-to-live zero in transit");
402 _ (EXC_FRAGTIME, "time-to-live zero during reassembly");
405 s = format (s, "unknown code 0x%x", icmp_code);
418 u8 * format_icmp4_packet (u8 * s, va_list * args)
420 u8 * p = va_arg (*args, u8 *);
421 struct iphdr * ip = (void *) p;
422 icmp4_t * icmp = (void *) (ip + 1);
423 s = format (s, "icmp %U %U -> %U",
424 format_icmp4_type_and_code, icmp->type, icmp->code,
425 format_network_address, AF_INET, &ip->saddr,
426 format_network_address, AF_INET, &ip->daddr);
431 u8 * format_ip4_tos_byte (u8 * s, va_list * args)
433 uword tos = va_arg (*args, uword);
435 if (tos & IPTOS_LOWDELAY)
436 s = format (s, "minimize-delay, ");
437 if (tos & IPTOS_MINCOST)
438 s = format (s, "minimize-cost, ");
439 if (tos & IPTOS_THROUGHPUT)
440 s = format (s, "maximize-throughput, ");
441 if (tos & IPTOS_RELIABILITY)
442 s = format (s, "maximize-reliability, ");
444 switch (IPTOS_PREC (tos))
446 #define _(x,y) case IPTOS_PREC_##x: s = format (s, y); break
447 _ (NETCONTROL, "network");
448 _ (INTERNETCONTROL, "internet");
449 _ (CRITIC_ECP, "critical");
451 _ (FLASHOVERRIDE, "flash-override");
452 _ (IMMEDIATE, "immediate");
453 _ (PRIORITY, "priority");
454 _ (ROUTINE, "routine");
461 u8 * format_ip4_packet (u8 * s, va_list * args)
463 u8 * p = va_arg (*args, u8 *);
464 struct iphdr * ip = (void *) p;
466 static format_function_t * f[256];
468 if (! f[IPPROTO_TCP])
470 f[IPPROTO_TCP] = format_tcp4_packet;
471 f[IPPROTO_UDP] = format_udp4_packet;
472 f[IPPROTO_ICMP] = format_icmp4_packet;
476 return format (s, "%U", f[ip->protocol], p);
478 s = format (s, "%U: %U -> %U",
479 format_network_protocol, AF_INET, ip->protocol,
480 format_network_address, AF_INET, &ip->saddr,
481 format_network_address, AF_INET, &ip->daddr);
486 #define foreach_unix_arphrd_type \
536 _ (IEEE802_TR, 800) \
538 _ (IEEE80211_PRISM, 802) \
539 _ (IEEE80211_RADIOTAP, 803) \
543 u8 * format_unix_arphrd (u8 * s, va_list * args)
545 #ifndef __COVERITY__ /* doesn't understand this at all... */
546 u32 x = va_arg (*args, u32);
550 #define _(f,n) case ARPHRD_##f: t = #f; break;
551 foreach_unix_arphrd_type
559 s = format (s, "%s", t);
561 s = format (s, "unknown 0x%x", x);
566 #define foreach_unix_interface_flag \
587 static char * unix_interface_flag_names[] = {
589 foreach_unix_interface_flag
593 u8 * format_unix_interface_flags (u8 * s, va_list * args)
595 u32 x = va_arg (*args, u32);
599 s = format (s, "none");
600 else foreach_set_bit (i, x, ({
601 if (i < ARRAY_LEN (unix_interface_flag_names))
602 s = format (s, "%s", unix_interface_flag_names[i]);
604 s = format (s, "unknown %d", i);
606 s = format (s, ", ");
612 u16 ar_hrd; /* format of hardware address */
613 u16 ar_pro; /* format of protocol address */
614 u8 ar_hln; /* length of hardware address */
615 u8 ar_pln; /* length of protocol address */
616 u16 ar_op; /* ARP opcode (command) */
617 u8 ar_sha[6]; /* sender hardware address */
618 u8 ar_spa[4]; /* sender IP address */
619 u8 ar_tha[6]; /* target hardware address */
620 u8 ar_tpa[4]; /* target IP address */
623 u8 * format_arp_packet (u8 * s, va_list * args)
625 arp_ether_ip4_t * a = va_arg (*args, arp_ether_ip4_t *);
626 char * op = "unknown";
628 if (a->ar_pro != ETH_P_IP ||
629 a->ar_hrd != ARPHRD_ETHER)
634 #define _(f) case ARPOP_##f: op = #f; break;
642 s = format (s, "%s %U %U -> %U %U",
644 format_network_address, AF_INET, a->ar_spa,
645 format_network_address, AF_UNSPEC, a->ar_sha,
646 format_network_address, AF_INET, a->ar_tpa,
647 format_network_address, AF_UNSPEC, a->ar_tha);
651 u8 * format_ethernet_proto (u8 * s, va_list * args)
653 uword type = va_arg (*args, uword);
658 case 0: t = "BPDU"; break;
659 #define _(f) case ETH_P_##f: t = #f; break;
686 #ifdef ETH_P_PPP_DISC
715 vec_add (s, t, strlen (t));
717 s = format (s, "ether-type 0x%x", type);
721 u8 * format_ethernet_packet (u8 * s, va_list * args)
723 struct ethhdr * h = va_arg (*args, struct ethhdr *);
724 uword proto = h->h_proto;
725 u8 * payload = (void *) (h + 1);
728 /* Check for 802.2/802.3 encapsulation. */
729 if (proto < ETH_DATA_LEN)
732 u8 dsap, ssap, control;
736 ethhdr_802_t * h1 = (void *) (h + 1);
738 payload = (void *) (h1 + 1);
741 indent = format_get_indent (s);
743 s = format (s, "%U: %U -> %U",
744 format_ethernet_proto, proto,
745 format_network_address, AF_UNSPEC, h->h_source,
746 format_network_address, AF_UNSPEC, h->h_dest);
751 s = format (s, "\n%U%U",
752 format_white_space, indent,
753 format_arp_packet, payload);
761 u8 * format_hostname (u8 * s, va_list * args)
765 if (gethostname (b, sizeof (buffer)) < 0)
767 return format (s, "%s", b);
772 u8 * format_timeval (u8 * s, va_list * args)
774 char * fmt = va_arg (*args, char *);
775 struct timeval * tv = va_arg (*args, struct timeval *);
781 fmt = "y/m/d H:M:S:F";
785 static struct timeval now;
786 gettimeofday (&now, 0);
790 msec = flt_round_nearest (1e-3 * tv->tv_usec);
792 { msec = 0; tv->tv_sec++; }
795 time_t t = tv->tv_sec;
799 for (f = fmt; *f; f++)
802 char * what_fmt = "%d";
811 what = 1900 + tm->tm_year;
815 what = tm->tm_mon + 1;
840 s = format (s, what_fmt, what);
847 u8 * format_time_float (u8 * s, va_list * args)
849 u8 * fmt = va_arg (*args, u8 *);
850 f64 t = va_arg (*args, f64);
853 t = unix_time_now ();
855 tv.tv_usec = 1e6*(t - tv.tv_sec);
856 return format (s, "%U", format_timeval, fmt, &tv);
859 u8 * format_signal (u8 * s, va_list * args)
861 uword signum = va_arg (*args, uword);
865 #define _(x) case x: t = #x; break;
903 return format (s, "unknown %d", signum);
906 vec_add (s, t, strlen (t));
910 u8 * format_ucontext_pc (u8 * s, va_list * args)
912 ucontext_t * uc __attribute__((unused));
913 unsigned long * regs = 0;
916 uc = va_arg (*args, ucontext_t *);
918 #if defined (powerpc)
919 regs = &uc->uc_mcontext.uc_regs->gregs[0];
920 #elif defined (powerpc64)
921 regs = &uc->uc_mcontext.uc_regs->gp_regs[0];
922 #elif defined (i386) || defined (__x86_64__)
923 regs = (void *) &uc->uc_mcontext.gregs[0];
926 #if defined (powerpc) || defined (powerpc64)
930 #elif defined (__x86_64__)
938 return format (s, "unsupported");
940 return format (s, "%p", regs[reg_no]);
944 unformat_unix_gid (unformat_input_t * input, va_list * args)
946 gid_t *gid = va_arg (*args, gid_t *);
947 struct group *grp = 0;
951 if (unformat (input, "%d", &r))
955 else if (unformat (input, "%s", &s))
957 grp = getgrnam ((char *) s);
968 #endif /* __KERNEL__ */