back to topotato report
topotato coverage report
Current view: top level - lib - ipaddr.h (source / functions) Hit Total Coverage
Test: test_bgp_aggregate_address_route_map.py::BGPAggregateAddressRouteMap Lines: 6 53 11.3 %
Date: 2023-02-24 18:36:44 Functions: 1 5 20.0 %

          Line data    Source code
       1             : /*
       2             :  * IP address structure (for generic IPv4 or IPv6 address)
       3             :  * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
       4             :  *
       5             :  * This file is part of FRR.
       6             :  *
       7             :  * FRR is free software; you can redistribute it and/or modify it
       8             :  * under the terms of the GNU General Public License as published by the
       9             :  * Free Software Foundation; either version 2, or (at your option) any
      10             :  * later version.
      11             :  *
      12             :  * FRR is distributed in the hope that it will be useful, but
      13             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with FRR; see the file COPYING.  If not, write to the Free
      19             :  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      20             :  * 02111-1307, USA.
      21             :  */
      22             : 
      23             : #ifndef __IPADDR_H__
      24             : #define __IPADDR_H__
      25             : 
      26             : #include <zebra.h>
      27             : 
      28             : #include "lib/log.h"
      29             : 
      30             : #ifdef __cplusplus
      31             : extern "C" {
      32             : #endif
      33             : 
      34             : /*
      35             :  * Generic IP address - union of IPv4 and IPv6 address.
      36             :  */
      37             : enum ipaddr_type_t {
      38             :         IPADDR_NONE = AF_UNSPEC,
      39             :         IPADDR_V4 = AF_INET,
      40             :         IPADDR_V6 = AF_INET6,
      41             : };
      42             : 
      43             : struct ipaddr {
      44             :         enum ipaddr_type_t ipa_type;
      45             :         union {
      46             :                 uint8_t addr;
      47             :                 struct in_addr _v4_addr;
      48             :                 struct in6_addr _v6_addr;
      49             :         } ip;
      50             : #define ipaddr_v4 ip._v4_addr
      51             : #define ipaddr_v6 ip._v6_addr
      52             : };
      53             : 
      54             : #define IS_IPADDR_NONE(p) ((p)->ipa_type == IPADDR_NONE)
      55             : #define IS_IPADDR_V4(p)   ((p)->ipa_type == IPADDR_V4)
      56             : #define IS_IPADDR_V6(p)   ((p)->ipa_type == IPADDR_V6)
      57             : 
      58             : #define SET_IPADDR_V4(p)  (p)->ipa_type = IPADDR_V4
      59             : #define SET_IPADDR_V6(p)  (p)->ipa_type = IPADDR_V6
      60             : 
      61             : #define IPADDRSZ(p)                                                            \
      62             :         (IS_IPADDR_V4((p)) ? sizeof(struct in_addr) : sizeof(struct in6_addr))
      63             : 
      64             : #define IPADDR_STRING_SIZE 46
      65             : 
      66           0 : static inline int ipaddr_family(const struct ipaddr *ip)
      67             : {
      68           0 :         switch (ip->ipa_type) {
      69             :         case IPADDR_V4:
      70             :                 return AF_INET;
      71           0 :         case IPADDR_V6:
      72           0 :                 return AF_INET6;
      73           0 :         case IPADDR_NONE:
      74           0 :                 return AF_UNSPEC;
      75             :         }
      76             : 
      77           0 :         assert(!"Reached end of function where we should never hit");
      78             : }
      79             : 
      80           0 : static inline int str2ipaddr(const char *str, struct ipaddr *ip)
      81             : {
      82           0 :         int ret;
      83             : 
      84           0 :         memset(ip, 0, sizeof(struct ipaddr));
      85             : 
      86           0 :         ret = inet_pton(AF_INET, str, &ip->ipaddr_v4);
      87           0 :         if (ret > 0) /* Valid IPv4 address. */
      88             :         {
      89           0 :                 ip->ipa_type = IPADDR_V4;
      90           0 :                 return 0;
      91             :         }
      92           0 :         ret = inet_pton(AF_INET6, str, &ip->ipaddr_v6);
      93           0 :         if (ret > 0) /* Valid IPv6 address. */
      94             :         {
      95           0 :                 ip->ipa_type = IPADDR_V6;
      96           0 :                 return 0;
      97             :         }
      98             : 
      99             :         return -1;
     100             : }
     101             : 
     102           0 : static inline char *ipaddr2str(const struct ipaddr *ip, char *buf, int size)
     103             : {
     104           0 :         buf[0] = '\0';
     105           0 :         if (ip)
     106           0 :                 inet_ntop(ip->ipa_type, &ip->ip.addr, buf, size);
     107           0 :         return buf;
     108             : }
     109             : 
     110             : #define IS_MAPPED_IPV6(A)                                                      \
     111             :         ((A)->s6_addr32[0] == 0x00000000                                       \
     112             :                  ? ((A)->s6_addr32[1] == 0x00000000                            \
     113             :                             ? (ntohl((A)->s6_addr32[2]) == 0xFFFF ? 1 : 0)     \
     114             :                             : 0)                                               \
     115             :                  : 0)
     116             : 
     117             : /*
     118             :  * Convert IPv4 address to IPv4-mapped IPv6 address which is of the
     119             :  * form ::FFFF:<IPv4 address> (RFC 4291). This IPv6 address can then
     120             :  * be used to represent the IPv4 address, wherever only an IPv6 address
     121             :  * is required.
     122             :  */
     123           0 : static inline void ipv4_to_ipv4_mapped_ipv6(struct in6_addr *in6,
     124             :                                             struct in_addr in)
     125             : {
     126           0 :         uint32_t addr_type = htonl(0xFFFF);
     127             : 
     128           0 :         memset(in6, 0, sizeof(struct in6_addr));
     129           0 :         memcpy((char *)in6 + 8, &addr_type, sizeof(addr_type));
     130           0 :         memcpy((char *)in6 + 12, &in, sizeof(struct in_addr));
     131             : }
     132             : 
     133             : /*
     134             :  * convert an ipv4 mapped ipv6 address back to ipv4 address
     135             :  */
     136           0 : static inline void ipv4_mapped_ipv6_to_ipv4(const struct in6_addr *in6,
     137             :                                             struct in_addr *in)
     138             : {
     139           0 :         memset(in, 0, sizeof(struct in_addr));
     140           0 :         memcpy(in, (char *)in6 + 12, sizeof(struct in_addr));
     141           0 : }
     142             : 
     143             : /*
     144             :  * generic ordering comparison between IP addresses
     145             :  */
     146          25 : static inline int ipaddr_cmp(const struct ipaddr *a, const struct ipaddr *b)
     147             : {
     148          25 :         uint32_t va, vb;
     149          25 :         va = a->ipa_type;
     150          25 :         vb = b->ipa_type;
     151          25 :         if (va != vb)
     152           0 :                 return (va < vb) ? -1 : 1;
     153          25 :         switch (a->ipa_type) {
     154           0 :         case IPADDR_V4:
     155           0 :                 va = ntohl(a->ipaddr_v4.s_addr);
     156           0 :                 vb = ntohl(b->ipaddr_v4.s_addr);
     157           0 :                 if (va != vb)
     158           0 :                         return (va < vb) ? -1 : 1;
     159             :                 return 0;
     160           0 :         case IPADDR_V6:
     161           0 :                 return memcmp((void *)&a->ipaddr_v6, (void *)&b->ipaddr_v6,
     162             :                               sizeof(a->ipaddr_v6));
     163             :         case IPADDR_NONE:
     164             :                 return 0;
     165             :         }
     166             : 
     167           0 :         assert(!"Reached end of function we should never hit");
     168             : }
     169             : 
     170           0 : static inline bool ipaddr_is_zero(const struct ipaddr *ip)
     171             : {
     172           0 :         switch (ip->ipa_type) {
     173             :         case IPADDR_NONE:
     174             :                 return true;
     175           0 :         case IPADDR_V4:
     176           0 :                 return ip->ipaddr_v4.s_addr == INADDR_ANY;
     177           0 :         case IPADDR_V6:
     178           0 :                 return IN6_IS_ADDR_UNSPECIFIED(&ip->ipaddr_v6);
     179             :         }
     180             :         return true;
     181             : }
     182             : 
     183             : #ifdef _FRR_ATTRIBUTE_PRINTFRR
     184             : #pragma FRR printfrr_ext "%pIA"  (struct ipaddr *)
     185             : #endif
     186             : 
     187             : #ifdef __cplusplus
     188             : }
     189             : #endif
     190             : 
     191             : #endif /* __IPADDR_H__ */

Generated by: LCOV version v1.16-topotato