LCOV - code coverage report
Current view: top level - lib/cmdline - cmdline_parse_ipaddr.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 45 45 100.0 %
Date: 2025-02-01 18:54:23 Functions: 2 2 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 42 45 93.3 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2010-2014 Intel Corporation.
       3                 :            :  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
       4                 :            :  * All rights reserved.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include <stdio.h>
       8                 :            : #include <stdlib.h>
       9                 :            : #include <string.h>
      10                 :            : #include <errno.h>
      11                 :            : 
      12                 :            : #include <rte_string_fns.h>
      13                 :            : 
      14                 :            : #include "cmdline_parse.h"
      15                 :            : #include "cmdline_parse_ipaddr.h"
      16                 :            : 
      17                 :            : struct cmdline_token_ops cmdline_token_ipaddr_ops = {
      18                 :            :         .parse = cmdline_parse_ipaddr,
      19                 :            :         .complete_get_nb = NULL,
      20                 :            :         .complete_get_elt = NULL,
      21                 :            :         .get_help = cmdline_get_help_ipaddr,
      22                 :            : };
      23                 :            : 
      24                 :            : #define PREFIXMAX 128
      25                 :            : #define V4PREFIXMAX 32
      26                 :            : 
      27                 :            : int
      28                 :        670 : cmdline_parse_ipaddr(cmdline_parse_token_hdr_t *tk, const char *buf, void *res,
      29                 :            :         unsigned ressize)
      30                 :            : {
      31                 :            :         struct cmdline_token_ipaddr *tk2;
      32                 :            :         unsigned int token_len = 0;
      33                 :            :         char ip_str[INET6_ADDRSTRLEN+4+1]; /* '+4' is for prefixlen (if any) */
      34                 :            :         cmdline_ipaddr_t ipaddr;
      35                 :            :         char *prefix, *prefix_end;
      36                 :            :         long prefixlen = 0;
      37                 :            : 
      38         [ +  - ]:        670 :         if (res && ressize < sizeof(cmdline_ipaddr_t))
      39                 :            :                 return -1;
      40                 :            : 
      41   [ +  +  +  + ]:        670 :         if (!buf || !tk || ! *buf)
      42                 :            :                 return -1;
      43                 :            : 
      44                 :            :         tk2 = (struct cmdline_token_ipaddr *)tk;
      45                 :            : 
      46         [ +  + ]:       9554 :         while (!cmdline_isendoftoken(buf[token_len]))
      47                 :       8899 :                 token_len++;
      48                 :            : 
      49                 :            :         /* if token is too big... */
      50         [ +  + ]:        655 :         if (token_len >= INET6_ADDRSTRLEN+4)
      51                 :            :                 return -1;
      52                 :            : 
      53         [ +  + ]:        649 :         strlcpy(ip_str, buf, token_len + 1);
      54                 :            : 
      55                 :            :         /* convert the network prefix */
      56         [ +  + ]:        649 :         if (tk2->ipaddr_data.flags & CMDLINE_IPADDR_NETWORK) {
      57                 :        324 :                 prefix = strrchr(ip_str, '/');
      58         [ +  + ]:        324 :                 if (prefix == NULL)
      59                 :            :                         return -1;
      60                 :        150 :                 *prefix = '\0';
      61                 :        150 :                 prefix ++;
      62                 :        150 :                 errno = 0;
      63                 :        150 :                 prefixlen = strtol(prefix, &prefix_end, 10);
      64   [ +  -  +  + ]:        150 :                 if (errno || (*prefix_end != '\0')
      65         [ +  + ]:        144 :                         || prefixlen < 0 || prefixlen > PREFIXMAX)
      66                 :            :                         return -1;
      67                 :        129 :                 ipaddr.prefixlen = prefixlen;
      68                 :            :         }
      69                 :            :         else {
      70                 :        325 :                 ipaddr.prefixlen = 0;
      71                 :            :         }
      72                 :            : 
      73                 :            :         /* convert the IP addr */
      74   [ +  +  +  + ]:        757 :         if ((tk2->ipaddr_data.flags & CMDLINE_IPADDR_V4) &&
      75         [ +  + ]:        340 :             inet_pton(AF_INET, ip_str, &ipaddr.addr.ipv4) == 1 &&
      76                 :            :                 prefixlen <= V4PREFIXMAX) {
      77                 :         35 :                 ipaddr.family = AF_INET;
      78         [ +  + ]:         35 :                 if (res)
      79                 :            :                         memcpy(res, &ipaddr, sizeof(ipaddr));
      80                 :         35 :                 return token_len;
      81                 :            :         }
      82   [ +  +  +  + ]:        704 :         if ((tk2->ipaddr_data.flags & CMDLINE_IPADDR_V6) &&
      83                 :        285 :             inet_pton(AF_INET6, ip_str, &ipaddr.addr.ipv6) == 1) {
      84                 :         46 :                 ipaddr.family = AF_INET6;
      85         [ +  - ]:         46 :                 if (res)
      86                 :            :                         memcpy(res, &ipaddr, sizeof(ipaddr));
      87                 :         46 :                 return token_len;
      88                 :            :         }
      89                 :            :         return -1;
      90                 :            : 
      91                 :            : }
      92                 :            : 
      93                 :        675 : int cmdline_get_help_ipaddr(cmdline_parse_token_hdr_t *tk, char *dstbuf,
      94                 :            :                             unsigned int size)
      95                 :            : {
      96                 :            :         struct cmdline_token_ipaddr *tk2;
      97                 :            : 
      98         [ +  + ]:        675 :         if (!tk || !dstbuf)
      99                 :            :                 return -1;
     100                 :            : 
     101                 :            :         tk2 = (struct cmdline_token_ipaddr *)tk;
     102                 :            : 
     103   [ +  +  +  +  :        673 :         switch (tk2->ipaddr_data.flags) {
                +  +  + ]
     104                 :        112 :         case CMDLINE_IPADDR_V4:
     105                 :        112 :                 snprintf(dstbuf, size, "IPv4");
     106                 :            :                 break;
     107                 :        112 :         case CMDLINE_IPADDR_V6:
     108                 :        112 :                 snprintf(dstbuf, size, "IPv6");
     109                 :            :                 break;
     110                 :        112 :         case CMDLINE_IPADDR_V4|CMDLINE_IPADDR_V6:
     111                 :        112 :                 snprintf(dstbuf, size, "IPv4/IPv6");
     112                 :            :                 break;
     113                 :        112 :         case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V4:
     114                 :        112 :                 snprintf(dstbuf, size, "IPv4 network");
     115                 :            :                 break;
     116                 :        112 :         case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V6:
     117                 :        112 :                 snprintf(dstbuf, size, "IPv6 network");
     118                 :            :                 break;
     119                 :        112 :         case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V4|CMDLINE_IPADDR_V6:
     120                 :        112 :                 snprintf(dstbuf, size, "IPv4/IPv6 network");
     121                 :            :                 break;
     122                 :          1 :         default:
     123                 :          1 :                 snprintf(dstbuf, size, "IPaddr (bad flags)");
     124                 :            :                 break;
     125                 :            :         }
     126                 :            :         return 0;
     127                 :            : }

Generated by: LCOV version 1.14