LCOV - code coverage report
Current view: top level - basic - ether-addr-util.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 41 41 100.0 %
Date: 2019-08-23 13:36:53 Functions: 4 4 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 51 62 82.3 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <net/ethernet.h>
       5                 :            : #include <stdio.h>
       6                 :            : #include <sys/types.h>
       7                 :            : 
       8                 :            : #include "ether-addr-util.h"
       9                 :            : #include "macro.h"
      10                 :            : #include "string-util.h"
      11                 :            : 
      12                 :         16 : char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
      13         [ -  + ]:         16 :         assert(addr);
      14         [ -  + ]:         16 :         assert(buffer);
      15                 :            : 
      16                 :            :         /* Like ether_ntoa() but uses %02x instead of %x to print
      17                 :            :          * ethernet addresses, which makes them look less funny. Also,
      18                 :            :          * doesn't use a static buffer. */
      19                 :            : 
      20                 :         96 :         sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
      21                 :         16 :                 addr->ether_addr_octet[0],
      22                 :         16 :                 addr->ether_addr_octet[1],
      23                 :         16 :                 addr->ether_addr_octet[2],
      24                 :         16 :                 addr->ether_addr_octet[3],
      25                 :         16 :                 addr->ether_addr_octet[4],
      26                 :         16 :                 addr->ether_addr_octet[5]);
      27                 :            : 
      28                 :         16 :         return buffer;
      29                 :            : }
      30                 :            : 
      31                 :        312 : int ether_addr_compare(const struct ether_addr *a, const struct ether_addr *b) {
      32                 :        312 :         return memcmp(a, b, ETH_ALEN);
      33                 :            : }
      34                 :            : 
      35                 :        216 : static void ether_addr_hash_func(const struct ether_addr *p, struct siphash *state) {
      36                 :        216 :         siphash24_compress(p, sizeof(struct ether_addr), state);
      37                 :        216 : }
      38                 :            : 
      39                 :            : DEFINE_HASH_OPS(ether_addr_hash_ops, struct ether_addr, ether_addr_hash_func, ether_addr_compare);
      40                 :            : 
      41                 :        268 : int ether_addr_from_string(const char *s, struct ether_addr *ret) {
      42                 :        268 :         size_t pos = 0, n, field;
      43                 :        268 :         char sep = '\0';
      44                 :        268 :         const char *hex = HEXDIGITS, *hexoff;
      45                 :            :         size_t x;
      46                 :            :         bool touched;
      47                 :            : 
      48                 :            : #define parse_fields(v)                                         \
      49                 :            :         for (field = 0; field < ELEMENTSOF(v); field++) {       \
      50                 :            :                 touched = false;                                \
      51                 :            :                 for (n = 0; n < (2 * sizeof(v[0])); n++) {      \
      52                 :            :                         if (s[pos] == '\0')                     \
      53                 :            :                                 break;                          \
      54                 :            :                         hexoff = strchr(hex, s[pos]);           \
      55                 :            :                         if (!hexoff)                            \
      56                 :            :                                 break;                          \
      57                 :            :                         assert(hexoff >= hex);                  \
      58                 :            :                         x = hexoff - hex;                       \
      59                 :            :                         if (x >= 16)                            \
      60                 :            :                                 x -= 6; /* A-F */               \
      61                 :            :                         assert(x < 16);                         \
      62                 :            :                         touched = true;                         \
      63                 :            :                         v[field] <<= 4;                         \
      64                 :            :                         v[field] += x;                          \
      65                 :            :                         pos++;                                  \
      66                 :            :                 }                                               \
      67                 :            :                 if (!touched)                                   \
      68                 :            :                         return -EINVAL;                         \
      69                 :            :                 if (field < (ELEMENTSOF(v)-1)) {                \
      70                 :            :                         if (s[pos] != sep)                      \
      71                 :            :                                 return -EINVAL;                 \
      72                 :            :                         else                                    \
      73                 :            :                                 pos++;                          \
      74                 :            :                 }                                               \
      75                 :            :         }
      76                 :            : 
      77         [ -  + ]:        268 :         assert(s);
      78         [ -  + ]:        268 :         assert(ret);
      79                 :            : 
      80                 :        268 :         s += strspn(s, WHITESPACE);
      81                 :        268 :         sep = s[strspn(s, hex)];
      82                 :            : 
      83         [ +  + ]:        268 :         if (sep == '.') {
      84                 :         56 :                 uint16_t shorts[3] = { 0 };
      85                 :            : 
      86   [ -  +  +  +  :        704 :                 parse_fields(shorts);
          -  +  -  +  -  
          +  +  +  -  +  
          +  +  +  +  +  
                      + ]
      87                 :            : 
      88         [ +  + ]:         40 :                 if (s[pos] != '\0')
      89                 :          8 :                         return -EINVAL;
      90                 :            : 
      91         [ +  + ]:        128 :                 for (n = 0; n < ELEMENTSOF(shorts); n++) {
      92                 :         96 :                         ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8);
      93                 :         96 :                         ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff);
      94                 :            :                 }
      95                 :            : 
      96   [ +  +  +  + ]:        212 :         } else if (IN_SET(sep, ':', '-')) {
      97                 :        180 :                 struct ether_addr out = ETHER_ADDR_NULL;
      98                 :            : 
      99   [ +  +  +  +  :       3048 :                 parse_fields(out.ether_addr_octet);
          -  +  +  +  -  
          +  +  +  +  +  
          +  +  +  +  +  
                      + ]
     100                 :            : 
     101         [ +  + ]:        140 :                 if (s[pos] != '\0')
     102                 :         36 :                         return -EINVAL;
     103                 :            : 
     104         [ +  + ]:        728 :                 for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++)
     105                 :        624 :                         ret->ether_addr_octet[n] = out.ether_addr_octet[n];
     106                 :            : 
     107                 :            :         } else
     108                 :         32 :                 return -EINVAL;
     109                 :            : 
     110                 :        136 :         return 0;
     111                 :            : }

Generated by: LCOV version 1.14