]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/ipaddr.h
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / ipaddr.h
index 3425d73fd804ba04f1e5492ab41c50ea1d4de69d..7f2d06548bdf9bce095ffeef114007b24d6a9259 100644 (file)
 /*
  * Generic IP address - union of IPv4 and IPv6 address.
  */
-enum ipaddr_type_t
-{
-  IPADDR_NONE = 0,
-  IPADDR_V4 = 1,            /* IPv4 */
-  IPADDR_V6 = 2,            /* IPv6 */
+enum ipaddr_type_t {
+       IPADDR_NONE = 0,
+       IPADDR_V4 = 1, /* IPv4 */
+       IPADDR_V6 = 2, /* IPv6 */
 };
 
-typedef struct ipaddr
-{
-  enum ipaddr_type_t ipa_type;
-  union
-    {
-      u_char addr;
-      struct in_addr _v4_addr;
-      struct in6_addr _v6_addr;
-    } ip;
+struct ipaddr {
+       enum ipaddr_type_t ipa_type;
+       union {
+               uint8_t addr;
+               struct in_addr _v4_addr;
+               struct in6_addr _v6_addr;
+       } ip;
 #define ipaddr_v4 ip._v4_addr
 #define ipaddr_v6 ip._v6_addr
-} ipaddr_t;
+};
 
 #define IS_IPADDR_NONE(p) ((p)->ipa_type == IPADDR_NONE)
 #define IS_IPADDR_V4(p)   ((p)->ipa_type == IPADDR_V4)
@@ -55,40 +52,64 @@ typedef struct ipaddr
 #define SET_IPADDR_V4(p)  (p)->ipa_type = IPADDR_V4
 #define SET_IPADDR_V6(p)  (p)->ipa_type = IPADDR_V6
 
-static inline int
-str2ipaddr (const char *str, ipaddr_t *ip)
+static inline int str2ipaddr(const char *str, struct ipaddr *ip)
 {
-  int ret;
+       int ret;
 
-  memset (ip, 0, sizeof (ipaddr_t));
+       memset(ip, 0, sizeof(struct ipaddr));
 
-  ret = inet_pton (AF_INET, str, &ip->ipaddr_v4);
-  if (ret > 0) /* Valid IPv4 address. */
-    {
-      ip->ipa_type = IPADDR_V4;
-      return 0;
-    }
-  ret = inet_pton (AF_INET6, str, &ip->ipaddr_v6);
-  if (ret > 0) /* Valid IPv6 address. */
-    {
-      ip->ipa_type = IPADDR_V6;
-      return 0;
-    }
+       ret = inet_pton(AF_INET, str, &ip->ipaddr_v4);
+       if (ret > 0) /* Valid IPv4 address. */
+       {
+               ip->ipa_type = IPADDR_V4;
+               return 0;
+       }
+       ret = inet_pton(AF_INET6, str, &ip->ipaddr_v6);
+       if (ret > 0) /* Valid IPv6 address. */
+       {
+               ip->ipa_type = IPADDR_V6;
+               return 0;
+       }
 
-  return -1;
+       return -1;
 }
 
-static inline char *
-ipaddr2str (ipaddr_t *ip, char *buf, int size)
+static inline char *ipaddr2str(struct ipaddr *ip, char *buf, int size)
 {
-  buf[0] = '\0';
-  if (ip)
-    {
-      if (IS_IPADDR_V4(ip))
-        inet_ntop (AF_INET, &ip->ip.addr, buf, size);
-      else if (IS_IPADDR_V6(ip))
-        inet_ntop (AF_INET6, &ip->ip.addr, buf, size);
-    }
-  return buf;
+       buf[0] = '\0';
+       if (ip) {
+               if (IS_IPADDR_V4(ip))
+                       inet_ntop(AF_INET, &ip->ip.addr, buf, size);
+               else if (IS_IPADDR_V6(ip))
+                       inet_ntop(AF_INET6, &ip->ip.addr, buf, size);
+       }
+       return buf;
 }
+
+/*
+ * Convert IPv4 address to IPv4-mapped IPv6 address which is of the
+ * form ::FFFF:<IPv4 address> (RFC 4291). This IPv6 address can then
+ * be used to represent the IPv4 address, wherever only an IPv6 address
+ * is required.
+ */
+static inline void ipv4_to_ipv4_mapped_ipv6(struct in6_addr *in6,
+                                           struct in_addr in)
+{
+       uint32_t addr_type = htonl(0xFFFF);
+
+       memset(in6, 0, sizeof(struct in6_addr));
+       memcpy((char *)in6 + 8, &addr_type, sizeof(addr_type));
+       memcpy((char *)in6 + 12, &in, sizeof(struct in_addr));
+}
+
+/*
+ * convert an ipv4 mapped ipv6 address back to ipv4 address
+ */
+static inline void ipv4_mapped_ipv6_to_ipv4(struct in6_addr *in6,
+                                           struct in_addr *in)
+{
+       memset(in, 0, sizeof(struct in_addr));
+       memcpy(in, (char *)in6 + 12, sizeof(struct in_addr));
+}
+
 #endif /* __IPADDR_H__ */