LCOV - code coverage report
Current view: top level - vppinfra - unix-formats.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 69 197 35.0 %
Date: 2023-07-05 22:20:52 Functions: 4 10 40.0 %

          Line data    Source code
       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 __USE_GNU
      54             : 
      55             : #include <unistd.h>
      56             : #include <signal.h>
      57             : #include <grp.h>
      58             : 
      59             : #include <time.h>
      60             : #include <sys/socket.h>
      61             : #include <netdb.h>
      62             : #include <math.h>
      63             : 
      64             : #include <vppinfra/time.h>
      65             : #if __linux__
      66             : #ifdef AF_NETLINK
      67             : #include <linux/types.h>
      68             : #include <linux/netlink.h>
      69             : #endif
      70             : #endif
      71             : 
      72             : #endif /* ! __KERNEL__ */
      73             : 
      74             : 
      75             : #ifdef __KERNEL__
      76             : # include <linux/socket.h>
      77             : # include <linux/in.h>
      78             : # include <linux/ip.h>
      79             : # include <linux/tcp.h>
      80             : # include <linux/udp.h>
      81             : # include <linux/icmp.h>
      82             : # include <linux/if_ether.h>
      83             : # include <linux/if_arp.h>
      84             : #else
      85             : # include <net/if.h>            /* struct ifnet may live here */
      86             : # include <netinet/in.h>
      87             : # include <netinet/ip.h>
      88             : # include <netinet/tcp.h>
      89             : # include <netinet/udp.h>
      90             : # include <netinet/ip_icmp.h>
      91             : # include <netinet/if_ether.h>
      92             : #endif /* __KERNEL__ */
      93             : 
      94             : #include <vppinfra/format.h>
      95             : #include <vppinfra/error.h>
      96             : 
      97             : /* Format unix network address family (e.g. AF_INET). */
      98           0 : u8 * format_address_family (u8 * s, va_list * va)
      99             : {
     100           0 :   uword family = va_arg (*va, uword);
     101           0 :   u8 * t = (u8 *) "UNKNOWN";
     102           0 :   switch (family)
     103             :     {
     104             : #define _(x) case PF_##x: t = (u8 *) #x; break
     105           0 :       _ (UNSPEC);
     106           0 :       _ (UNIX);                 /* Unix domain sockets          */
     107           0 :       _ (INET);                 /* Internet IP Protocol         */
     108             : #ifdef PF_AX25
     109           0 :       _ (AX25);                 /* Amateur Radio AX.25          */
     110             : #endif
     111             : #ifdef PF_IPX
     112           0 :       _ (IPX);                  /* Novell IPX                   */
     113             : #endif
     114             : #ifdef PF_APPLETALK
     115           0 :       _ (APPLETALK);            /* AppleTalk DDP                */
     116             : #endif
     117             : #ifdef PF_NETROM
     118           0 :       _ (NETROM);               /* Amateur Radio NET/ROM        */
     119             : #endif
     120             : #ifdef PF_BRIDGE
     121           0 :       _ (BRIDGE);               /* Multiprotocol bridge         */
     122             : #endif
     123             : #ifdef PF_ATMPVC
     124           0 :       _ (ATMPVC);               /* ATM PVCs                     */
     125             : #endif
     126             : #ifdef PF_X25
     127           0 :       _ (X25);                  /* Reserved for X.25 project    */
     128             : #endif
     129             : #ifdef PF_INET6
     130           0 :       _ (INET6);                /* IP version 6                 */
     131             : #endif
     132             : #ifdef PF_ROSE
     133           0 :       _ (ROSE);                 /* Amateur Radio X.25 PLP       */
     134             : #endif
     135             : #ifdef PF_DECnet
     136           0 :       _ (DECnet);               /* Reserved for DECnet project  */
     137             : #endif
     138             : #ifdef PF_NETBEUI
     139           0 :       _ (NETBEUI);              /* Reserved for 802.2LLC project*/
     140             : #endif
     141             : #ifdef PF_SECURITY
     142           0 :       _ (SECURITY);             /* Security callback pseudo AF */
     143             : #endif
     144             : #ifdef PF_KEY
     145           0 :       _ (KEY);                  /* PF_KEY key management API */
     146             : #endif
     147             : #ifdef PF_NETLINK
     148           0 :       _ (NETLINK);
     149             : #endif
     150             : #ifdef PF_PACKET
     151           0 :       _ (PACKET);               /* Packet family                */
     152             : #endif
     153             : #ifdef PF_ASH
     154           0 :       _ (ASH);                  /* Ash                          */
     155             : #endif
     156             : #ifdef PF_ECONET
     157           0 :       _ (ECONET);               /* Acorn Econet                 */
     158             : #endif
     159             : #ifdef PF_ATMSVC
     160           0 :       _ (ATMSVC);               /* ATM SVCs                     */
     161             : #endif
     162             : #ifdef PF_SNA
     163           0 :       _ (SNA);                  /* Linux SNA Project */
     164             : #endif
     165             : #ifdef PF_IRDA
     166           0 :       _ (IRDA);                 /* IRDA sockets                 */
     167             : #endif
     168             : #undef _
     169             :     }
     170           0 :   vec_add (s, t, strlen ((char *) t));
     171           0 :   return s;
     172             : }
     173             : 
     174           0 : u8 * format_network_protocol (u8 * s, va_list * args)
     175             : {
     176           0 :   uword family = va_arg (*args, uword);
     177           0 :   uword protocol = va_arg (*args, uword);
     178             : 
     179             : #ifndef __KERNEL__
     180           0 :   struct protoent * p = getprotobynumber (protocol);
     181             : 
     182           0 :   ASSERT (family == AF_INET);
     183           0 :   if (p)
     184           0 :     return format (s, "%s", p->p_name);
     185             :   else
     186           0 :     return format (s, "%d", protocol);
     187             : #else
     188             :   return format (s, "%d/%d", family, protocol);
     189             : #endif
     190             : }
     191             : 
     192           0 : u8 * format_network_port (u8 * s, va_list * args)
     193             : {
     194           0 :   uword proto = va_arg (*args, uword);
     195           0 :   uword port = va_arg (*args, uword);
     196             : 
     197             : #ifndef __KERNEL__
     198           0 :   struct servent * p = getservbyport (port, proto == IPPROTO_UDP ? "udp" : "tcp");
     199             : 
     200           0 :   if (p)
     201           0 :     return format (s, "%s", p->s_name);
     202             :   else
     203           0 :     return format (s, "%d", port);
     204             : #else
     205             :   return format (s, "%s/%d", proto == IPPROTO_UDP ? "udp" : "tcp", port);
     206             : #endif
     207             : }
     208             : 
     209             : /* Format generic network address: takes two arguments family and address.
     210             :    Assumes network byte order. */
     211           0 : u8 * format_network_address (u8 * s, va_list * args)
     212             : {
     213           0 :   uword family = va_arg (*args, uword);
     214           0 :   u8 * addr    = va_arg (*args, u8 *);
     215             : 
     216           0 :   switch (family)
     217             :     {
     218           0 :     case AF_INET:
     219           0 :       s = format (s, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
     220           0 :       break;
     221             : 
     222           0 :     case AF_UNSPEC:
     223             :       /* We use AF_UNSPEC for ethernet addresses. */
     224           0 :       s = format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
     225           0 :                   addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
     226           0 :       break;
     227             : 
     228           0 :     default:
     229           0 :       clib_error ("unsupported address family %d", family);
     230             :     }
     231             : 
     232           0 :   return s;
     233             : }
     234             : 
     235           0 : u8 * format_sockaddr (u8 * s, va_list * args)
     236             : {
     237           0 :   void * v = va_arg (*args, void *);
     238           0 :   struct sockaddr * sa = v;
     239             :   static u32 local_counter;
     240             : 
     241           0 :   switch (sa->sa_family)
     242             :     {
     243           0 :     case AF_INET:
     244             :       {
     245           0 :         struct sockaddr_in * i = v;
     246           0 :         s = format (s, "%U:%U",
     247             :                     format_network_address, AF_INET, &i->sin_addr.s_addr,
     248           0 :                     format_network_port, IPPROTO_TCP, ntohs (i->sin_port));
     249             :       }
     250           0 :       break;
     251             : 
     252           0 :     case AF_LOCAL:
     253             :       {
     254             :         /* 
     255             :          * There isn't anything useful to print.
     256             :          * The unix cli world uses the output to make a node name,
     257             :          * so we need to return a unique name. 
     258             :          */
     259           0 :         s = format (s, "local:%u", local_counter++);
     260             :       }
     261           0 :       break;
     262             : 
     263             : #ifndef __KERNEL__
     264             : #ifdef AF_NETLINK
     265           0 :     case AF_NETLINK:
     266             :       {
     267           0 :         struct sockaddr_nl * n = v;
     268           0 :         s = format (s, "KERNEL-NETLINK");
     269           0 :         if (n->nl_groups)
     270           0 :           s = format (s, " (groups 0x%x)", n->nl_groups);
     271           0 :         break;
     272             :       }
     273             : #endif
     274             : #endif
     275             : 
     276           0 :     default:
     277           0 :       s = format (s, "sockaddr family %d", sa->sa_family);
     278           0 :       break;
     279             :     }
     280             : 
     281           0 :   return s;
     282             : }
     283             : 
     284             : #ifndef __APPLE__
     285             : 
     286             : #ifndef __KERNEL__
     287      269852 : u8 * format_timeval (u8 * s, va_list * args)
     288             : {
     289      269852 :   char * fmt = va_arg (*args, char *);
     290      269852 :   struct timeval * tv = va_arg (*args, struct timeval *);
     291             :   struct tm * tm;
     292             :   word msec;
     293             :   char * f, c;
     294             : 
     295      269852 :   if (! fmt)
     296      269852 :     fmt = "y/m/d H:M:S:F";
     297             : 
     298      269852 :   if (! tv)
     299             :     {
     300             :       static struct timeval now;
     301           0 :       gettimeofday (&now, 0);
     302           0 :       tv = &now;
     303             :     }
     304             : 
     305      269852 :   msec = flt_round_nearest (1e-3 * tv->tv_usec);
     306      269852 :   if (msec >= 1000)
     307         209 :     { msec = 0; tv->tv_sec++; }
     308             : 
     309             :   {
     310      269852 :     time_t t = tv->tv_sec;
     311      269852 :     tm = localtime (&t);
     312             :   }
     313             : 
     314     3777930 :   for (f = fmt; *f; f++)
     315             :     {
     316             :       uword what;
     317     3508080 :       char * what_fmt = "%d";
     318             : 
     319     3508080 :       switch (c = *f)
     320             :         {
     321     1619110 :         default:
     322     1619110 :           vec_add1 (s, c);
     323     1619110 :           continue;
     324             : 
     325      269852 :         case 'y':
     326      269852 :           what = 1900 + tm->tm_year;
     327      269852 :           what_fmt = "%4d";
     328      269852 :           break;
     329      269852 :         case 'm':
     330      269852 :           what = tm->tm_mon + 1;
     331      269852 :           what_fmt = "%02d";
     332      269852 :           break;
     333      269852 :         case 'd':
     334      269852 :           what = tm->tm_mday;
     335      269852 :           what_fmt = "%02d";
     336      269852 :           break;
     337      269852 :         case 'H':
     338      269852 :           what = tm->tm_hour;
     339      269852 :           what_fmt = "%02d";
     340      269852 :           break;
     341      269852 :         case 'M':
     342      269852 :           what = tm->tm_min;
     343      269852 :           what_fmt = "%02d";
     344      269852 :           break;
     345      269852 :         case 'S':
     346      269852 :           what = tm->tm_sec;
     347      269852 :           what_fmt = "%02d";
     348      269852 :           break;
     349      269852 :         case 'F':
     350      269852 :           what = msec;
     351      269852 :           what_fmt = "%03d";
     352      269852 :           break;
     353             :         }
     354             : 
     355     1888960 :       s = format (s, what_fmt, what);
     356             :     }
     357             : 
     358      269852 :   return s;
     359             : }
     360             : #endif
     361             : 
     362      269852 : u8 * format_time_float (u8 * s, va_list * args)
     363             : {
     364      269852 :   u8 * fmt = va_arg (*args, u8 *);
     365      269852 :   f64 t = va_arg (*args, f64);
     366             :   struct timeval tv;
     367      269852 :   if (t <= 0)
     368           0 :     t = unix_time_now ();
     369      269852 :   tv.tv_sec = t;
     370      269852 :   tv.tv_usec = 1e6*(t - tv.tv_sec);
     371      269852 :   return format (s, "%U", format_timeval, fmt, &tv);
     372             : }
     373             : 
     374         559 : u8 * format_signal (u8 * s, va_list * args)
     375             : {
     376         559 :   uword signum = va_arg (*args, uword);
     377         559 :   char * t = 0;
     378         559 :   switch (signum)
     379             :     {
     380             : #define _(x) case x: t = #x; break;
     381           0 :       _ (SIGHUP);
     382           0 :       _ (SIGINT);
     383           0 :       _ (SIGQUIT);
     384           0 :       _ (SIGILL);
     385           0 :       _ (SIGTRAP);
     386           0 :       _ (SIGABRT);
     387           0 :       _ (SIGBUS);
     388           0 :       _ (SIGFPE);
     389           0 :       _ (SIGKILL);
     390           0 :       _ (SIGUSR1);
     391           0 :       _ (SIGSEGV);
     392           0 :       _ (SIGUSR2);
     393           0 :       _ (SIGPIPE);
     394           0 :       _ (SIGALRM);
     395         559 :       _ (SIGTERM);
     396             : #ifdef SIGSTKFLT
     397           0 :       _ (SIGSTKFLT);
     398             : #endif
     399           0 :       _ (SIGCHLD);
     400           0 :       _ (SIGCONT);
     401           0 :       _ (SIGSTOP);
     402           0 :       _ (SIGTSTP);
     403           0 :       _ (SIGTTIN);
     404           0 :       _ (SIGTTOU);
     405           0 :       _ (SIGURG);
     406           0 :       _ (SIGXCPU);
     407           0 :       _ (SIGXFSZ);
     408           0 :       _ (SIGVTALRM);
     409           0 :       _ (SIGPROF);
     410           0 :       _ (SIGWINCH);
     411           0 :       _ (SIGIO);
     412           0 :       _ (SIGPWR);
     413             : #ifdef SIGSYS
     414           0 :       _ (SIGSYS);
     415             : #endif
     416             : #undef _
     417           0 :     default:
     418           0 :       return format (s, "unknown %d", signum);
     419             :     }
     420             : 
     421         559 :   vec_add (s, t, strlen (t));
     422         559 :   return s;
     423             : }
     424             : 
     425         559 : u8 * format_ucontext_pc (u8 * s, va_list * args)
     426             : {
     427             :   ucontext_t * uc __attribute__((unused));
     428         559 :   unsigned long * regs = 0;
     429         559 :   uword reg_no = 0;
     430             : 
     431         559 :   uc = va_arg (*args, ucontext_t *);
     432             : 
     433             : #if defined (powerpc)
     434             :   regs = &uc->uc_mcontext.uc_regs->gregs[0];
     435             : #elif defined (powerpc64)
     436             :   regs = &uc->uc_mcontext.uc_regs->gp_regs[0];
     437             : #elif defined (i386) || defined (__x86_64__)
     438         559 :   regs = (void *) &uc->uc_mcontext.gregs[0];
     439             : #elif defined(__aarch64__)
     440             :   regs = (void *) &uc->uc_mcontext.pc;
     441             : #endif
     442             : 
     443             : #if defined (powerpc) || defined (powerpc64)
     444             :   reg_no = PT_NIP;
     445             : #elif defined (i386)
     446             :   reg_no = REG_EIP;
     447             : #elif defined (__x86_64__)
     448         559 :   reg_no = REG_RIP;
     449             : #elif defined(__aarch64__)
     450             :   reg_no = 0;
     451             : #else
     452             :   reg_no = 0;
     453             :   regs = 0;
     454             : #endif
     455             : 
     456         559 :   if (! regs)
     457           0 :     return format (s, "unsupported");
     458             :   else
     459         559 :     return format (s, "%p", regs[reg_no]);
     460             : }
     461             : 
     462             : __clib_export uword
     463           0 : unformat_unix_gid (unformat_input_t * input, va_list * args)
     464             : {
     465           0 :   gid_t *gid = va_arg (*args, gid_t *);
     466           0 :   struct group *grp = 0;
     467             :   int r;
     468             :   u8 *s;
     469             : 
     470           0 :   if (unformat (input, "%d", &r))
     471             :     {
     472           0 :       grp = getgrgid (r);
     473             :     }
     474           0 :   else if (unformat (input, "%s", &s))
     475             :     {
     476           0 :       grp = getgrnam ((char *) s);
     477           0 :       vec_free (s);
     478             :     }
     479           0 :   if (grp)
     480             :     {
     481           0 :       *gid = grp->gr_gid;
     482           0 :       return 1;
     483             :     }
     484           0 :   return 0;
     485             : }
     486             : 
     487             : #endif /* __KERNEL__ */

Generated by: LCOV version 1.14