]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Integrated IP functions.
authorOndrej Zajicek <santiago@crfreenet.org>
Fri, 24 Oct 2014 09:11:43 +0000 (11:11 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Fri, 24 Oct 2014 09:11:43 +0000 (11:11 +0200)
25 files changed:
conf/cf-lex.l
conf/confbase.Y
lib/Modules
lib/ip.c
lib/ip.h
lib/ipv4.c [deleted file]
lib/ipv4.h [deleted file]
lib/ipv6.c [deleted file]
lib/ipv6.h [deleted file]
lib/printf.c
lib/socket.h
proto/bgp/attrs.c
proto/bgp/bgp.c
proto/bgp/config.Y
proto/bgp/packets.c
proto/ospf/ospf.h
proto/ospf/packet.c
proto/ospf/rt.c
proto/ospf/topology.c
proto/radv/packets.c
proto/radv/radv.h
proto/rip/rip.c
sysdep/bsd/krt-sock.c
sysdep/unix/io.c
sysdep/unix/unix.h

index 35b590bbd931ae7c6d504c09d13fafc30b833f03..b3e13311e27db6b712c328f2992a60d2f31b70d4 100644 (file)
@@ -124,22 +124,24 @@ include   ^{WHITE}*include{WHITE}*\".*\"{WHITE}*;
 }
 
 {DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+ {
+  ip4_addr a;
+  if (!ip4_pton(yytext, &a))
+    cf_error("Invalid IPv4 address %s", yytext);
+
 #ifdef IPV6
-  if (ipv4_pton_u32(yytext, &cf_lval.i32))
-    return RTRID;
-  cf_error("Invalid IPv4 address %s", yytext);
+  cf_lval.i32 = ip4_to_u32(a);
+  return RTRID;
 #else
-  if (ip_pton(yytext, &cf_lval.a))
-    return IPA;
-  cf_error("Invalid IP address %s", yytext);
+  cf_lval.a = ipa_from_ip4(a);
+  return IPA;
 #endif
 }
 
 ({XIGIT}*::|({XIGIT}*:){3,})({XIGIT}*|{DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+) {
 #ifdef IPV6
-  if (ip_pton(yytext, &cf_lval.a))
+  if (ipa_pton(yytext, &cf_lval.a))
     return IPA;
-  cf_error("Invalid IP address %s", yytext);
+  cf_error("Invalid IPv6 address %s", yytext);
 #else
   cf_error("This is an IPv4 router, therefore IPv6 addresses are not supported");
 #endif
index 49831b1ab48c46c01f2f08d9fee8aa435b6ec079..16a493e9b8af3b8023bc689bdb69a51ca100ce20 100644 (file)
@@ -187,7 +187,7 @@ pxlen:
      $$ = $2;
    }
  | ':' ipa {
-     $$ = ipa_mklen($2);
+     $$ = ipa_masklen($2);
      if ($$ < 0) cf_error("Invalid netmask %I", $2);
    }
  ;
index 7131f0b2788d37c20acfe7dc8d000addfaf5741e..7254df2d086be9512c451d764481a5a634346e00 100644 (file)
@@ -3,13 +3,6 @@ bitops.c
 bitops.h
 ip.h
 ip.c
-#ifdef IPV6
-ipv6.c
-ipv6.h
-#else
-ipv4.c
-ipv4.h
-#endif
 lists.c
 lists.h
 md5.c
index aa61553eada0a80f9e25142a98b8edc6c27da2fd..01edf0d5a5e600e4978c41c77462b85c12bd8530 100644 (file)
--- a/lib/ip.c
+++ b/lib/ip.c
@@ -1,14 +1,11 @@
 /*
- *     BIRD Library -- IP address routines common for IPv4 and IPv6
+ *     BIRD Library -- IP address functions
  *
  *     (c) 1998--2000 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 
-#include "nest/bird.h"
-#include "lib/ip.h"
-
 /**
  * DOC: IP addresses
  *
  * they must be manipulated using the following functions and macros.
  */
 
+#include <stdlib.h>
+
+#include "nest/bird.h"
+#include "lib/ip.h"
+
+
+int
+ip6_compare(ip6_addr a, ip6_addr b)
+{
+  int i;
+  for (i=0; i<4; i++)
+    if (a.addr[i] > b.addr[i])
+      return 1;
+    else if (a.addr[i] < b.addr[i])
+      return -1;
+  return 0;
+}
+
+ip6_addr
+ip6_mkmask(uint n)
+{
+  ip6_addr a;
+  int i;
+
+  for (i=0; i<4; i++)
+  {
+    if (!n)
+      a.addr[i] = 0;
+    else if (n >= 32)
+    {
+      a.addr[i] = ~0;
+      n -= 32;
+    }
+    else
+    {
+      a.addr[i] = u32_mkmask(n);
+      n = 0;
+    }
+  }
+
+  return a;
+}
+
+int
+ip6_masklen(ip6_addr *a)
+{
+  int i, j, n;
+
+  for (i=0, n=0; i<4; i++, n+=32)
+    if (a->addr[i] != ~0U)
+    {
+      j = u32_masklen(a->addr[i]);
+      if (j < 0)
+       return j;
+      n += j;
+      while (++i < 4)
+       if (a->addr[i])
+         return -1;
+      break;
+    }
+
+  return n;
+}
+
+int
+ip4_classify(ip4_addr ad)
+{
+  u32 a = _I(ad);
+  u32 b = a >> 24U;
+
+  if (b && b <= 0xdf)
+  {
+    if (b == 0x7f)
+      return IADDR_HOST | SCOPE_HOST;
+    else if ((b == 0x0a) ||
+            ((a & 0xffff0000) == 0xc0a80000) ||
+            ((a & 0xfff00000) == 0xac100000))
+      return IADDR_HOST | SCOPE_SITE;
+    else
+      return IADDR_HOST | SCOPE_UNIVERSE;
+  }
+
+  if (b >= 0xe0 && b <= 0xef)
+    return IADDR_MULTICAST | SCOPE_UNIVERSE;
+
+  if (a == 0xffffffff)
+    return IADDR_BROADCAST | SCOPE_LINK;
+
+  return IADDR_INVALID;
+}
+
+int
+ip6_classify(ip6_addr *a)
+{
+  u32 x = a->addr[0];
+
+  if ((x & 0xe0000000) == 0x20000000)          /* 2000::/3  Aggregatable Global Unicast Address */
+    return IADDR_HOST | SCOPE_UNIVERSE;
+  if ((x & 0xffc00000) == 0xfe800000)          /* fe80::/10 Link-Local Address */
+    return IADDR_HOST | SCOPE_LINK;
+  if ((x & 0xffc00000) == 0xfec00000)          /* fec0::/10 Site-Local Address */
+    return IADDR_HOST | SCOPE_SITE;
+  if ((x & 0xfe000000) == 0xfc000000)          /* fc00::/7  Unique Local Unicast Address (RFC 4193) */
+    return IADDR_HOST | SCOPE_SITE;
+  if ((x & 0xff000000) == 0xff000000)          /* ff00::/8  Multicast Address */
+  {
+    uint scope = (x >> 16) & 0x0f;
+    switch (scope)
+    {
+    case 1:  return IADDR_MULTICAST | SCOPE_HOST;
+    case 2:  return IADDR_MULTICAST | SCOPE_LINK;
+    case 5:  return IADDR_MULTICAST | SCOPE_SITE;
+    case 8:  return IADDR_MULTICAST | SCOPE_ORGANIZATION;
+    case 14: return IADDR_MULTICAST | SCOPE_UNIVERSE;
+    default: return IADDR_MULTICAST | SCOPE_UNDEFINED;
+    }
+  }
+
+  if (!x && !a->addr[1])
+  {
+    u32 a2 = a->addr[2];
+    u32 a3 = a->addr[3];
+
+    if (a2 == 0 && a3 == 1)
+      return IADDR_HOST | SCOPE_HOST;          /* Loopback address */
+    if (a2 == 0)
+      return ip4_classify(_MI4(a3));           /* IPv4 compatible addresses */
+    if (a2 == 0xffff)
+      return ip4_classify(_MI4(a3));           /* IPv4 mapped addresses */
+
+    return IADDR_INVALID;
+  }
+
+  return IADDR_HOST | SCOPE_UNDEFINED;
+}
+
+
+
+/*
+ *  Conversion of IPv6 address to presentation format and vice versa.
+ *  Heavily inspired by routines written by Paul Vixie for the BIND project
+ *  and of course by RFC 2373.
+ */
+
+
+char *
+ip4_ntop(ip4_addr a, char *b)
+{
+  u32 x = _I(a);
+  return b + bsprintf(b, "%d.%d.%d.%d", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff);
+}
+
+
+char *
+ip6_ntop(ip6_addr a, char *b)
+{
+  u16 words[8];
+  int bestpos, bestlen, curpos, curlen, i;
+
+  /* First of all, preprocess the address and find the longest run of zeros */
+  bestlen = bestpos = curpos = curlen = 0;
+  for (i=0; i<8; i++)
+  {
+    u32 x = a.addr[i/2];
+    words[i] = ((i%2) ? x : (x >> 16)) & 0xffff;
+    if (words[i])
+      curlen = 0;
+    else
+    {
+      if (!curlen)
+       curpos = i;
+      curlen++;
+      if (curlen > bestlen)
+      {
+       bestpos = curpos;
+       bestlen = curlen;
+      }
+    }
+  }
+
+  if (bestlen < 2)
+    bestpos = -1;
+
+  /* Is it an encapsulated IPv4 address? */
+  if (!bestpos && ((bestlen == 5 && a.addr[2] == 0xffff) || (bestlen == 6)))
+  {
+    u32 x = a.addr[3];
+    b += bsprintf(b, "::%s%d.%d.%d.%d",
+                 a.addr[2] ? "ffff:" : "",
+                 (x >> 24) & 0xff,
+                 (x >> 16) & 0xff,
+                 (x >> 8) & 0xff,
+                 x & 0xff);
+    return b;
+  }
+
+  /* Normal IPv6 formatting, compress the largest sequence of zeros */
+  for (i=0; i<8; i++)
+  {
+    if (i == bestpos)
+    {
+      i += bestlen - 1;
+      *b++ = ':';
+      if (i == 7)
+       *b++ = ':';
+    }
+    else
+    {
+      if (i)
+       *b++ = ':';
+      b += bsprintf(b, "%x", words[i]);
+    }
+  }
+  *b = 0;
+  return b;
+}
+
+int
+ip4_pton(char *a, ip4_addr *o)
+{
+  int i;
+  unsigned long int l;
+  u32 ia = 0;
+
+  i=4;
+  while (i--)
+  {
+    char *d, *c = strchr(a, '.');
+    if (!c != !i)
+      return 0;
+    l = strtoul(a, &d, 10);
+    if (d != c && *d || l > 255)
+      return 0;
+    ia = (ia << 8) | l;
+    if (c)
+      c++;
+    a = c;
+  }
+  *o = ip4_from_u32(ia);
+  return 1;
+}
+
+int
+ip6_pton(char *a, ip6_addr *o)
+{
+  u16 words[8];
+  int i, j, k, l, hfil;
+  char *start;
+
+  if (a[0] == ':')                     /* Leading :: */
+  {
+    if (a[1] != ':')
+      return 0;
+    a++;
+  }
+
+  hfil = -1;
+  i = 0;
+  while (*a)
+  {
+    if (*a == ':')                     /* :: */
+    {
+      if (hfil >= 0)
+       return 0;
+
+      hfil = i;
+      a++;
+      continue;
+    }
+
+    j = 0;
+    l = 0;
+    start = a;
+    for (;;)
+    {
+      if (*a >= '0' && *a <= '9')
+       k = *a++ - '0';
+      else if (*a >= 'A' && *a <= 'F')
+       k = *a++ - 'A' + 10;
+      else if (*a >= 'a' && *a <= 'f')
+       k = *a++ - 'a' + 10;
+      else
+       break;
+
+      j = (j << 4) + k;
+      if (j >= 0x10000 || ++l > 4)
+       return 0;
+    }
+
+    if (*a == ':' && a[1])
+      a++;
+    else if (*a == '.' && (i == 6 || i < 6 && hfil >= 0))
+    {                          /* Embedded IPv4 address */
+      ip4_addr x;
+      if (!ip4_pton(start, &x))
+       return 0;
+      words[i++] = _I(x) >> 16;
+      words[i++] = _I(x);
+      break;
+    }
+    else if (*a)
+      return 0;
+
+    if (i >= 8)
+      return 0;
+
+    words[i++] = j;
+  }
+
+  /* Replace :: with an appropriate number of zeros */
+  if (hfil >= 0)
+  {
+    j = 8 - i;
+    for (i=7; i-j >= hfil; i--)
+      words[i] = words[i-j];
+    for (; i>=hfil; i--)
+      words[i] = 0;
+  }
+
+  /* Convert the address to ip6_addr format */
+  for (i=0; i<4; i++)
+    o->addr[i] = (words[2*i] << 16) | words[2*i+1];
+
+  return 1;
+}
+
+
 /**
  * ip_scope_text - get textual representation of address scope
  * @scope: scope (%SCOPE_xxx)
  * Returns a pointer to a textual name of the scope given.
  */
 char *
-ip_scope_text(unsigned scope)
+ip_scope_text(uint scope)
 {
   static char *scope_table[] = { "host", "link", "site", "org", "univ", "undef" };
 
@@ -35,6 +359,23 @@ ip_scope_text(unsigned scope)
     return scope_table[scope];
 }
 
+ip4_addr
+ip4_class_mask(ip4_addr ad)
+{
+  u32 m, a = _I(ad);
+
+  if (a < 0x80000000)
+    m = 0xff000000;
+  else if (a < 0xc0000000)
+    m = 0xffff0000;
+  else
+    m = 0xffffff00;
+  if (a & ~m)
+    m = 0xffffffff;
+
+  return _MI4(m);
+}
+
 #if 0
 /**
  * ipa_equal - compare two IP addresses for equality
@@ -102,14 +443,14 @@ ip_addr ipa_not(ip_addr x) { DUMMY }
 ip_addr ipa_mkmask(int x) { DUMMY }
 
 /**
- * ipa_mkmask - calculate netmask length
+ * ipa_masklen - calculate netmask length
  * @x: IP address
  *
  * This function checks whether @x represents a valid netmask and
  * returns the size of the associate network prefix or -1 for invalid
  * mask.
  */
-int ipa_mklen(ip_addr x) { DUMMY }
+int ipa_masklen(ip_addr x) { DUMMY }
 
 /**
  * ipa_hash - hash IP addresses
@@ -151,8 +492,8 @@ void ipa_ntoh(ip_addr x) { DUMMY }
 int ipa_classify(ip_addr x) { DUMMY }
 
 /**
- * ipa_class_mask - guess netmask according to address class
- * @x: IP address
+ * ip4_class_mask - guess netmask according to address class
+ * @x: IPv4 address
  *
  * This function (available in IPv4 version only) returns a
  * network mask according to the address class of @x. Although
@@ -160,7 +501,7 @@ int ipa_classify(ip_addr x) { DUMMY }
  * routing protocols transferring no prefix lengths nor netmasks
  * and this function could be useful to them.
  */
-ip_addr ipa_class_mask(ip_addr x) { DUMMY }
+ip4_addr ip4_class_mask(ip4_addr x) { DUMMY }
 
 /**
  * ipa_from_u32 - convert IPv4 address to an integer
@@ -193,7 +534,7 @@ ip_addr ipa_to_u32(u32 x) { DUMMY }
 int ipa_compare(ip_addr x, ip_addr y) { DUMMY }
 
 /**
- * ipa_build - build an IPv6 address from parts
+ * ipa_build6 - build an IPv6 address from parts
  * @a1: part #1
  * @a2: part #2
  * @a3: part #3
@@ -203,18 +544,7 @@ int ipa_compare(ip_addr x, ip_addr y) { DUMMY }
  * address. It's used for example when a protocol wants to bind its
  * socket to a hard-wired multicast address.
  */
-ip_addr ipa_build(u32 a1, u32 a2, u32 a3, u32 a4) { DUMMY }
-
-/**
- * ipa_absolutize - convert link scope IPv6 address to universe scope
- * @x: link scope IPv6 address
- * @y: universe scope IPv6 prefix of the interface
- *
- * This function combines a link-scope IPv6 address @x with the universe
- * scope prefix @x of the network assigned to an interface to get a
- * universe scope form of @x.
- */
-ip_addr ipa_absolutize(ip_addr x, ip_addr y) { DUMMY }
+ip_addr ipa_build6(u32 a1, u32 a2, u32 a3, u32 a4) { DUMMY }
 
 /**
  * ip_ntop - convert IP address to textual representation
index 023c1064451286fa744ce4000595179ee360f2cb..45e073d9f31c5476bee67a654dbb8b67647aacbf 100644 (file)
--- a/lib/ip.h
+++ b/lib/ip.h
 #ifndef _BIRD_IP_H_
 #define _BIRD_IP_H_
 
-#ifndef IPV6
-#include "ipv4.h"
+#include "lib/endian.h"
+#include "lib/string.h"
+#include "lib/bitops.h"
+#include "lib/unaligned.h"
+
+
+#define IP4_OSPF_ALL_ROUTERS   ipa_build4(224, 0, 0, 5)
+#define IP4_OSPF_DES_ROUTERS   ipa_build4(224, 0, 0, 6)
+
+#define IP6_ALL_NODES          ipa_build6(0xFF020000, 0, 0, 1)
+#define IP6_ALL_ROUTERS                ipa_build6(0xFF020000, 0, 0, 2)
+#define IP6_OSPF_ALL_ROUTERS   ipa_build6(0xFF020000, 0, 0, 5)
+#define IP6_OSPF_DES_ROUTERS   ipa_build6(0xFF020000, 0, 0, 6)
+#define IP6_RIP_ROUTERS                ipa_build6(0xFF020000, 0, 0, 9)
+
+#define IP4_NONE               _MI4(0)
+#define IP6_NONE               _MI6(0,0,0,0)
+
+#define IP4_MIN_MTU            576
+#define IP6_MIN_MTU            1280
+
+#define IP_PREC_INTERNET_CONTROL 0xc0
+
+
+#ifdef IPV6
+#define MAX_PREFIX_LENGTH 128
+#define BITS_PER_IP_ADDRESS 128
+#define STD_ADDRESS_P_LENGTH 39
+#define SIZE_OF_IP_HEADER 40
 #else
-#include "ipv6.h"
+#define MAX_PREFIX_LENGTH 32
+#define BITS_PER_IP_ADDRESS 32
+#define STD_ADDRESS_P_LENGTH 15
+#define SIZE_OF_IP_HEADER 24
+#endif
+
+
+#ifdef DEBUGGING
+
+typedef struct ip4_addr {
+  u32 addr;
+} ip4_addr;
+
+#define _MI4(x) ((struct ip4_addr) { x })
+#define _I(x) (x).addr
+
+#else
+
+typedef u32 ip4_addr;
+
+#define _MI4(x) (x)
+#define _I(x) (x)
+
+#endif
+
+
+typedef struct ip6_addr {
+  u32 addr[4];
+} ip6_addr;
+
+#define _MI6(a,b,c,d) ((struct ip6_addr) {{ a, b, c, d }})
+#define _I0(a) ((a).addr[0])
+#define _I1(a) ((a).addr[1])
+#define _I2(a) ((a).addr[2])
+#define _I3(a) ((a).addr[3])
+
+
+#ifdef IPV6
+
+/* Structure ip_addr may contain both IPv4 and IPv6 addresses */
+typedef ip6_addr ip_addr;
+#define IPA_NONE IP6_NONE
+
+#define ipa_from_ip4(x) _MI6(0,0,0xffff,_I(x))
+#define ipa_from_ip6(x) x
+#define ipa_from_u32(x) ipa_from_ip4(ip4_from_u32(x))
+
+#define ipa_to_ip4(x) _MI4(_I3(x))
+#define ipa_to_ip6(x) x
+#define ipa_to_u32(x) ip4_to_u32(ipa_to_ip4(x))
+
+#define ipa_is_ip4(a) ip6_is_v4mapped(a)
+
+#else
+
+/* Provisionary ip_addr definition same as ip4_addr */
+typedef ip4_addr ip_addr;
+#define IPA_NONE IP4_NONE
+
+#define ipa_from_ip4(x) x
+#define ipa_from_ip6(x) IPA_NONE
+#define ipa_from_u32(x) ipa_from_ip4(ip4_from_u32(x))
+
+#define ipa_to_ip4(x) x
+#define ipa_to_ip6(x) IP6_NONE
+#define ipa_to_u32(x) ip4_to_u32(ipa_to_ip4(x))
+
+#define ipa_is_ip4(a) 1
+
+#endif
+
+
+/*
+ *     Public constructors
+ */
+
+#define ip4_from_u32(x) _MI4(x)
+#define ip4_to_u32(x) _I(x)
+
+#define ip4_build(a,b,c,d) _MI4(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+#define ip6_build(a,b,c,d) _MI6(a,b,c,d)
+
+#define ipa_build4(a,b,c,d) ipa_from_ip4(ip4_build(a,b,c,d))
+#define ipa_build6(a,b,c,d) ipa_from_ip6(ip6_build(a,b,c,d))
+
+
+/*
+ *     Basic algebraic functions
+ */
+
+static inline int ip4_equal(ip4_addr a, ip4_addr b)
+{ return _I(a) == _I(b); }
+
+static inline int ip4_zero(ip4_addr a)
+{ return _I(a) == 0; }
+
+static inline int ip4_nonzero(ip4_addr a)
+{ return _I(a) != 0; }
+
+static inline ip4_addr ip4_and(ip4_addr a, ip4_addr b)
+{ return _MI4(_I(a) & _I(b)); }
+
+static inline ip4_addr ip4_or(ip4_addr a, ip4_addr b)
+{ return _MI4(_I(a) | _I(b)); }
+
+static inline ip4_addr ip4_xor(ip4_addr a, ip4_addr b)
+{ return _MI4(_I(a) ^ _I(b)); }
+
+static inline ip4_addr ip4_not(ip4_addr a)
+{ return _MI4(~_I(a)); }
+
+
+static inline int ip6_equal(ip6_addr a, ip6_addr b)
+{ return _I0(a) == _I0(b) && _I1(a) == _I1(b) && _I2(a) == _I2(b) && _I3(a) == _I3(b); }
+
+static inline int ip6_zero(ip6_addr a)
+{ return  !_I0(a) && !_I1(a) && !_I2(a) && !_I3(a); }
+
+static inline int ip6_nonzero(ip6_addr a)
+{ return _I0(a) || _I1(a) || _I2(a) || _I3(a); }
+
+static inline ip6_addr ip6_and(ip6_addr a, ip6_addr b)
+{ return _MI6(_I0(a) & _I0(b), _I1(a) & _I1(b), _I2(a) & _I2(b), _I3(a) & _I3(b)); }
+
+static inline ip6_addr ip6_or(ip6_addr a, ip6_addr b)
+{ return _MI6(_I0(a) | _I0(b), _I1(a) | _I1(b), _I2(a) | _I2(b), _I3(a) | _I3(b)); }
+
+static inline ip6_addr ip6_xor(ip6_addr a, ip6_addr b)
+{ return _MI6(_I0(a) ^ _I0(b), _I1(a) ^ _I1(b), _I2(a) ^ _I2(b), _I3(a) ^ _I3(b)); }
+
+static inline ip6_addr ip6_not(ip6_addr a)
+{ return _MI6(~_I0(a), ~_I1(a), ~_I2(a), ~_I3(a)); }
+
+
+#ifdef IPV6
+#define ipa_equal(x,y) ip6_equal(x,y)
+#define ipa_zero(x) ip6_zero(x)
+#define ipa_nonzero(x) ip6_nonzero(x)
+#define ipa_and(x,y) ip6_and(x,y)
+#define ipa_or(x,y) ip6_or(x,y)
+#define ipa_xor(x,y) ip6_xor(x,y)
+#define ipa_not(x) ip6_not(x)
+#else
+#define ipa_equal(x,y) ip4_equal(x,y)
+#define ipa_zero(x) ip4_zero(x)
+#define ipa_nonzero(x) ip4_nonzero(x)
+#define ipa_and(x,y) ip4_and(x,y)
+#define ipa_or(x,y) ip4_or(x,y)
+#define ipa_xor(x,y) ip4_xor(x,y)
+#define ipa_not(x) ip4_not(x)
+#endif
+
+
+
+#ifdef IPV6
+/*
+ * A zero address is either a token for invalid/unused, or the prefix of default
+ * routes. These functions should be used in the second case, where both IPv4
+ * and IPv6 zero addresses should be checked.
+ */
+
+static inline int ipa_zero2(ip_addr a)
+{ return  !_I0(a) && !_I1(a) && ((_I2(a) == 0) || (_I2(a) == 0xffff)) && !_I3(a); }
+
+static inline int ipa_nonzero2(ip_addr a)
+{ return _I0(a) || _I1(a) || ((_I2(a) != 0) && (_I2(a) != 0xffff)) || _I3(a); }
+
+#else
+#define ipa_zero2(x) ip4_zero(x)
+#define ipa_nonzero2(x) ip4_nonzero(x)
+#endif
+
+
+/*
+ *     Hash and compare functions
+ */
+
+static inline uint ip4_hash(ip4_addr a)
+{
+  /* Returns a 16-bit value */
+  u32 x = _I(a);
+  x ^= x >> 16;
+  x ^= x << 10;
+  return x & 0xffff;
+}
+
+static inline u32 ip4_hash32(ip4_addr a)
+{
+  /* Returns a 32-bit value, although low-order bits are not mixed */
+  u32 x = _I(a);
+  x ^= x << 16;
+  x ^= x << 12;
+  return x;
+}
+
+static inline uint ip6_hash(ip6_addr a)
+{
+  /* Returns a 16-bit hash key */
+  u32 x = _I0(a) ^ _I1(a) ^ _I2(a) ^ _I3(a);
+  return (x ^ (x >> 16) ^ (x >> 8)) & 0xffff;
+}
+
+static inline u32 ip6_hash32(ip6_addr a)
+{
+  /* Returns a 32-bit hash key, although low-order bits are not mixed */
+  u32 x = _I0(a) ^ _I1(a) ^ _I2(a) ^ _I3(a);
+  return x ^ (x << 16) ^ (x << 24);
+}
+
+static inline int ip4_compare(ip4_addr a, ip4_addr b)
+{ return (_I(a) > _I(b)) - (_I(a) < _I(b)); }
+
+int ip6_compare(ip6_addr a, ip6_addr b);
+
+
+#ifdef IPV6
+#define ipa_hash(x) ip6_hash(x)
+#define ipa_hash32(x) ip6_hash32(x)
+#define ipa_compare(x,y) ip6_compare(x,y)
+#else
+#define ipa_hash(x) ip4_hash(x)
+#define ipa_hash32(x) ip4_hash32(x)
+#define ipa_compare(x,y) ip4_compare(x,y)
 #endif
 
-#define ipa_zero(x) (!ipa_nonzero(x))
-#define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l)))))
-#define ipa_in_net(x,n,p) (ipa_zero(ipa_and(ipa_xor((n),(x)),ipa_mkmask(p))))
-#define net_in_net(n1,l1,n2,l2) (((l1) >= (l2)) && (ipa_zero(ipa_and(ipa_xor((n1),(n2)),ipa_mkmask(l2)))))
 
 /*
- *     ip_classify() returns either a negative number for invalid addresses
- *     or scope OR'ed together with address type.
+ *     IP address classification
  */
 
+/* Address class */
 #define IADDR_INVALID          -1
 #define IADDR_SCOPE_MASK               0xfff
 #define IADDR_HOST             0x1000
 #define IADDR_BROADCAST                0x2000
 #define IADDR_MULTICAST                0x4000
 
+/* Address scope */
+#define SCOPE_HOST             0
+#define SCOPE_LINK             1
+#define SCOPE_SITE             2
+#define SCOPE_ORGANIZATION     3
+#define SCOPE_UNIVERSE         4
+#define SCOPE_UNDEFINED                5
+
+int ip4_classify(ip4_addr ad);
+int ip6_classify(ip6_addr *a);
+
+static inline int ip6_is_link_local(ip6_addr a)
+{ return (_I0(a) & 0xffc00000) == 0xfe800000; }
+
+static inline int ip6_is_v4mapped(ip6_addr a)
+{ return _I0(a) == 0 && _I1(a) == 0 && _I2(a) == 0xffff; }
+
+#ifdef IPV6
+#define ipa_classify(x) ip6_classify(&(x))
+#define ipa_is_link_local(x) ip6_is_link_local(x)
+#else
+#define ipa_classify(x) ip4_classify(x)
+#define ipa_is_link_local(x) 0
+#endif
+
+static inline int ipa_classify_net(ip_addr a)
+{ return ipa_zero2(a) ? (IADDR_HOST | SCOPE_UNIVERSE) : ipa_classify(a); }
+
+
 /*
- *     Address scope
+ *     Miscellaneous IP prefix manipulation
  */
 
-#define SCOPE_HOST 0
-#define SCOPE_LINK 1
-#define SCOPE_SITE 2
-#define SCOPE_ORGANIZATION 3
-#define SCOPE_UNIVERSE 4
-#define SCOPE_UNDEFINED 5
+static inline ip4_addr ip4_mkmask(uint n)
+{ return _MI4(u32_mkmask(n)); }
+
+static inline int ip4_masklen(ip4_addr a)
+{ return u32_masklen(_I(a)); }
+
+ip6_addr ip6_mkmask(uint n);
+int ip6_masklen(ip6_addr *a);
+
+/* ipX_pxlen() requires that x != y */
+static inline uint ip4_pxlen(ip4_addr a, ip4_addr b)
+{ return 31 - u32_log2(_I(a) ^ _I(b)); }
+
+static inline uint ip6_pxlen(ip6_addr a, ip6_addr b)
+{
+  int i = 0;
+  i += (a.addr[i] == b.addr[i]);
+  i += (a.addr[i] == b.addr[i]);
+  i += (a.addr[i] == b.addr[i]);
+  i += (a.addr[i] == b.addr[i]);
+  return 32 * i + 31 - u32_log2(a.addr[i] ^ b.addr[i]);
+}
+
+static inline u32 ip4_getbit(ip4_addr a, uint pos)
+{ return _I(a) & (0x80000000 >> pos); }
+
+static inline u32 ip6_getbit(ip6_addr a, uint pos)
+{ return a.addr[pos / 32] & (0x80000000 >> (pos % 32)); }
+
+static inline ip4_addr ip4_opposite_m1(ip4_addr a)
+{ return _MI4(_I(a) ^ 1); }
+
+static inline ip4_addr ip4_opposite_m2(ip4_addr a)
+{ return _MI4(_I(a) ^ 3); }
+
+static inline ip6_addr ip6_opposite_m1(ip6_addr a)
+{ return _MI6(_I0(a), _I1(a), _I2(a), _I3(a) ^ 1); }
+
+static inline ip6_addr ip6_opposite_m2(ip6_addr a)
+{ return _MI6(_I0(a), _I1(a), _I2(a), _I3(a) ^ 3); }
+
+ip4_addr ip4_class_mask(ip4_addr ad);
+
+#ifdef IPV6
+#define ipa_mkmask(x) ip6_mkmask(x)
+#define ipa_masklen(x) ip6_masklen(&x)
+#define ipa_pxlen(x,y) ip6_pxlen(x,y)
+#define ipa_getbit(x,n) ip6_getbit(x,n)
+#define ipa_opposite_m1(x) ip6_opposite_m1(x)
+#define ipa_opposite_m2(x) ip6_opposite_m2(x)
+#else
+#define ipa_mkmask(x) ip4_mkmask(x)
+#define ipa_masklen(x) ip4_masklen(x)
+#define ipa_pxlen(x,y) ip4_pxlen(x,y)
+#define ipa_getbit(x,n) ip4_getbit(x,n)
+#define ipa_opposite_m1(x) ip4_opposite_m1(x)
+#define ipa_opposite_m2(x) ip4_opposite_m2(x)
+#endif
 
-char *ip_scope_text(unsigned);
 
 /*
- *     Network prefixes
+ *     Host/network order conversions
  */
 
-struct prefix {
-  ip_addr addr;
-  unsigned int len;
-};
+static inline ip4_addr ip4_hton(ip4_addr a)
+{ return _MI4(htonl(_I(a))); }
+
+static inline ip4_addr ip4_ntoh(ip4_addr a)
+{ return _MI4(ntohl(_I(a))); }
+
+static inline ip6_addr ip6_hton(ip6_addr a)
+{ return _MI6(htonl(_I0(a)), htonl(_I1(a)), htonl(_I2(a)), htonl(_I3(a))); }
+
+static inline ip6_addr ip6_ntoh(ip6_addr a)
+{ return _MI6(ntohl(_I0(a)), ntohl(_I1(a)), ntohl(_I2(a)), ntohl(_I3(a))); }
+
+#ifdef IPV6
+#define ipa_hton(x) x = ip6_hton(x)
+#define ipa_ntoh(x) x = ip6_ntoh(x)
+#else
+#define ipa_hton(x) x = ip4_hton(x)
+#define ipa_ntoh(x) x = ip4_ntoh(x)
+#endif
+
+
+/*
+ *     Unaligned data access (in network order)
+ */
+
+static inline ip4_addr get_ip4(void *buf)
+{
+  return _MI4(get_u32(buf));
+}
+
+static inline ip6_addr get_ip6(void *buf)
+{
+  ip6_addr a;
+  memcpy(&a, buf, 16);
+  return ip6_ntoh(a);
+}
+
+static inline void * put_ip4(void *buf, ip4_addr a)
+{
+  put_u32(buf, _I(a));
+  return buf+4;
+}
+
+static inline void * put_ip6(void *buf, ip6_addr a)
+{
+  a = ip6_hton(a);
+  memcpy(buf, &a, 16);
+  return buf+16;
+}
+
+// XXXX these functions must be redesigned or removed
+#ifdef IPV6
+#define get_ipa(x) get_ip6(x)
+#define put_ipa(x,y) put_ip6(x,y)
+#else
+#define get_ipa(x) get_ip4(x)
+#define put_ipa(x,y) put_ip4(x,y)
+#endif
+
+
+/*
+ *     Binary/text form conversions
+ */
+
+char *ip4_ntop(ip4_addr a, char *b);
+char *ip6_ntop(ip6_addr a, char *b);
+
+static inline char * ip4_ntox(ip4_addr a, char *b)
+{ return b + bsprintf(b, "%08x", _I(a)); }
+
+static inline char * ip6_ntox(ip6_addr a, char *b)
+{ return b + bsprintf(b, "%08x.%08x.%08x.%08x", _I0(a), _I1(a), _I2(a), _I3(a)); }
+
+int ip4_pton(char *a, ip4_addr *o);
+int ip6_pton(char *a, ip6_addr *o);
+
+// XXXX these functions must be redesigned or removed
+#ifdef IPV6
+#define ipa_ntop(x,y) ip6_ntop(x,y)
+#define ipa_ntox(x,y) ip6_ntox(x,y)
+#define ipa_pton(x,y) ip6_pton(x,y)
+#else
+#define ipa_ntop(x,y) ip4_ntop(x,y)
+#define ipa_ntox(x,y) ip4_ntox(x,y)
+#define ipa_pton(x,y) ip4_pton(x,y)
+#endif
 
-static inline int ipa_classify_net(ip_addr a)
-{ return ipa_zero(a) ? (IADDR_HOST | SCOPE_UNIVERSE) : ipa_classify(a); }
 
 /*
- *     Conversions between internal and string representation
+ *     Miscellaneous
  */
 
-char *ip_ntop(ip_addr a, char *);
-char *ip_ntox(ip_addr a, char *);
-int ip_pton(char *a, ip_addr *o);
+// XXXX review this
+
+#define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l)))))
+#define ipa_in_net(x,n,p) (ipa_zero(ipa_and(ipa_xor((n),(x)),ipa_mkmask(p))))
+#define net_in_net(n1,l1,n2,l2) (((l1) >= (l2)) && (ipa_zero(ipa_and(ipa_xor((n1),(n2)),ipa_mkmask(l2)))))
+
+char *ip_scope_text(unsigned);
+
+struct prefix {
+  ip_addr addr;
+  unsigned int len;
+};
+
 
 #endif
diff --git a/lib/ipv4.c b/lib/ipv4.c
deleted file mode 100644 (file)
index 751351c..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- *     BIRD Library -- IPv4 Address Manipulation Functions
- *
- *     (c) 1998 Martin Mares <mj@ucw.cz>
- *
- *     Can be freely distributed and used under the terms of the GNU GPL.
- */
-
-#include <stdlib.h>
-
-#include "nest/bird.h"
-#include "lib/ip.h"
-#include "lib/string.h"
-
-int
-ipv4_classify(u32 a)
-{
-  u32 b = a >> 24U;
-
-  if (b && b <= 0xdf)
-    {
-      if (b == 0x7f)
-       return IADDR_HOST | SCOPE_HOST;
-      else if (b == 0x0a ||
-              (a & 0xffff0000) == 0xc0a80000 ||
-              (a & 0xfff00000) == 0xac100000)
-       return IADDR_HOST | SCOPE_SITE;
-      else
-       return IADDR_HOST | SCOPE_UNIVERSE;
-    }
-  if (b >= 0xe0 && b <= 0xef)
-    return IADDR_MULTICAST | SCOPE_UNIVERSE;
-  if (a == 0xffffffff)
-    return IADDR_BROADCAST | SCOPE_LINK;
-  return IADDR_INVALID;
-}
-
-char *
-ip_ntop(ip_addr a, char *b)
-{
-  u32 x = _I(a);
-
-  return b + bsprintf(b, "%d.%d.%d.%d",
-                     ((x >> 24) & 0xff),
-                     ((x >> 16) & 0xff),
-                     ((x >> 8) & 0xff),
-                     (x & 0xff));
-}
-
-char *
-ip_ntox(ip_addr a, char *b)
-{
-  return b + bsprintf(b, "%08x", _I(a));
-}
-
-u32
-ipv4_class_mask(u32 a)
-{
-       u32 m;
-
-       if (a < 0x80000000)
-               m = 0xff000000;
-       else if (a < 0xc0000000)
-               m = 0xffff0000;
-       else
-               m = 0xffffff00;
-       while (a & ~m)
-               m |= m >> 1;
-       return m;
-}
-
-int
-ip_pton(char *a, ip_addr *o)
-{
-  int i;
-  unsigned long int l;
-  u32 ia = 0;
-
-  i=4;
-  while (i--)
-    {
-      char *d, *c = strchr(a, '.');
-      if (!c != !i)
-       return 0;
-      l = strtoul(a, &d, 10);
-      if (d != c && *d || l > 255)
-       return 0;
-      ia = (ia << 8) | l;
-      if (c)
-       c++;
-      a = c;
-    }
-  *o = ipa_from_u32(ia);
-  return 1;
-}
-
-byte *
-ipv4_skip_header(byte *pkt, int *len)
-{
-  int l = *len;
-  int q;
-
-  if (l < 20 || (*pkt & 0xf0) != 0x40)
-    return NULL;
-  q = (*pkt & 0x0f) * 4;
-  if (q > l)
-    return NULL;
-  *len -= q;
-  return pkt + q;
-}
diff --git a/lib/ipv4.h b/lib/ipv4.h
deleted file mode 100644 (file)
index 7fbdf2e..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- *     BIRD -- IP Addresses et Cetera for IPv4
- *
- *     (c) 1998--1999 Martin Mares <mj@ucw.cz>
- *
- *     Can be freely distributed and used under the terms of the GNU GPL.
- */
-
-#ifndef _BIRD_IPV4_H_
-#define _BIRD_IPV4_H_
-
-#include "lib/endian.h"
-#include "lib/bitops.h"
-#include "lib/unaligned.h"
-
-#ifdef DEBUGGING
-
-/*
- *     Use the structural representation when you want to make sure
- *     nobody unauthorized attempts to handle ip_addr as number.
- */
-
-typedef struct ipv4_addr {
-  u32 addr;
-} ip_addr;
-
-#define _I(x) (x).addr
-#define _MI(x) ((struct ipv4_addr) { x })
-
-#else
-
-typedef u32 ip_addr;
-
-#define _I(x) (x)
-#define _MI(x) (x)
-
-#endif
-
-#define MAX_PREFIX_LENGTH 32
-#define BITS_PER_IP_ADDRESS 32
-#define STD_ADDRESS_P_LENGTH 15
-#define SIZE_OF_IP_HEADER 24
-
-#define IPA_NONE (_MI(0))
-
-#define ipa_equal(x,y) (_I(x) == _I(y))
-#define ipa_nonzero(x) _I(x)
-#define ipa_and(x,y) _MI(_I(x) & _I(y))
-#define ipa_or(x,y) _MI(_I(x) | _I(y))
-#define ipa_xor(x,y) _MI(_I(x) ^ _I(y))
-#define ipa_not(x) _MI(~_I(x))
-#define ipa_mkmask(x) _MI(u32_mkmask(x))
-#define ipa_mklen(x) u32_masklen(_I(x))
-#define ipa_hash(x) ipv4_hash(_I(x))
-#define ipa_hash32(x) ipv4_hash32(_I(x))
-#define ipa_hton(x) x = _MI(htonl(_I(x)))
-#define ipa_ntoh(x) x = _MI(ntohl(_I(x)))
-#define ipa_classify(x) ipv4_classify(_I(x))
-#define ipa_has_link_scope(x) ipv4_has_link_scope(_I(x))
-#define ipa_opposite_m1(x) _MI(_I(x) ^ 1)
-#define ipa_opposite_m2(x) _MI(_I(x) ^ 3)
-#define ipa_class_mask(x) _MI(ipv4_class_mask(_I(x)))
-#define ipa_from_u32(x) _MI(x)
-#define ipa_to_u32(x) _I(x)
-#define ipa_compare(x,y) ipv4_compare(_I(x),_I(y))
-/* ipa_pxlen() requires that x != y */
-#define ipa_pxlen(x, y) ipv4_pxlen(_I(x), _I(y))
-#define ipa_getbit(x, y) (_I(x) & (0x80000000 >> (y)))
-#define ipa_put_addr(x, y) ipv4_put_addr(x, y)
-
-#define ip_skip_header(x, y) ipv4_skip_header(x, y)
-
-int ipv4_classify(u32);
-u32 ipv4_class_mask(u32);
-byte *ipv4_skip_header(byte *, int *);
-
-static inline int ipv4_has_link_scope(u32 a UNUSED)
-{
-  return 0;
-}
-
-static inline unsigned ipv4_hash(u32 a)
-{
-  /* Returns a 16-bit value */
-  a ^= a >> 16;
-  a ^= a << 10;
-  return a & 0xffff;
-}
-
-static inline u32 ipv4_hash32(u32 a)
-{
-  /* Returns a 32-bit value, although low-order bits are not mixed */
-  a ^= a << 16;
-  a ^= a << 12;
-  return a;
-}
-
-static inline int ipv4_compare(u32 x, u32 y)
-{
-  return (x > y) - (x < y);
-}
-
-static inline u32 ipv4_pxlen(u32 a, u32 b)
-{
-  return 31 - u32_log2(a ^ b);
-}
-
-static inline byte * ipv4_put_addr(byte *buf, ip_addr a)
-{
-  put_u32(buf, _I(a));
-  return buf+4;
-}
-
-#define IP_PREC_INTERNET_CONTROL 0xc0
-
-#endif
diff --git a/lib/ipv6.c b/lib/ipv6.c
deleted file mode 100644 (file)
index 623f632..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- *     BIRD Library -- IPv6 Address Manipulation Functions
- *
- *     (c) 1999 Martin Mares <mj@ucw.cz>
- *
- *     Can be freely distributed and used under the terms of the GNU GPL.
- */
-
-#include <stdlib.h>
-
-#include "nest/bird.h"
-#include "lib/ip.h"
-#include "lib/bitops.h"
-#include "lib/endian.h"
-#include "lib/string.h"
-
-/*
- *  See RFC 2373 for explanation of IPv6 addressing issues.
- */
-
-ip_addr
-ipv6_mkmask(unsigned n)
-{
-  ip_addr a;
-  int i;
-
-  for(i=0; i<4; i++)
-    {
-      if (!n)
-       a.addr[i] = 0;
-      else if (n >= 32)
-       {
-         a.addr[i] = ~0;
-         n -= 32;
-       }
-      else
-       {
-         a.addr[i] = u32_mkmask(n);
-         n = 0;
-       }
-    }
-  return a;
-}
-
-unsigned
-ipv6_mklen(ip_addr *a)
-{
-  int i, j, n;
-
-  for(i=0, n=0; i<4; i++, n+=32)
-    if (a->addr[i] != ~0U)
-      {
-       j = u32_masklen(a->addr[i]);
-       if (j < 0)
-         return j;
-       n += j;
-       while (++i < 4)
-         if (a->addr[i])
-           return -1;
-       break;
-      }
-  return n;
-}
-
-int
-ipv6_classify(ip_addr *a)
-{
-  u32 x = a->addr[0];
-
-  if ((x & 0xe0000000) == 0x20000000)          /* 2000::/3  Aggregatable Global Unicast Address */
-    return IADDR_HOST | SCOPE_UNIVERSE;
-  if ((x & 0xffc00000) == 0xfe800000)          /* fe80::/10 Link-Local Address */
-    return IADDR_HOST | SCOPE_LINK;
-  if ((x & 0xffc00000) == 0xfec00000)          /* fec0::/10 Site-Local Address */
-    return IADDR_HOST | SCOPE_SITE;
-  if ((x & 0xfe000000) == 0xfc000000)          /* fc00::/7  Unique Local Unicast Address (RFC 4193) */
-    return IADDR_HOST | SCOPE_SITE;
-  if ((x & 0xff000000) == 0xff000000)          /* ff00::/8  Multicast Address */
-    {
-      unsigned int scope = (x >> 16) & 0x0f;
-      switch (scope)
-       {
-       case 1:  return IADDR_MULTICAST | SCOPE_HOST;
-       case 2:  return IADDR_MULTICAST | SCOPE_LINK;
-       case 5:  return IADDR_MULTICAST | SCOPE_SITE;
-       case 8:  return IADDR_MULTICAST | SCOPE_ORGANIZATION;
-       case 14: return IADDR_MULTICAST | SCOPE_UNIVERSE;
-       default: return IADDR_MULTICAST | SCOPE_UNDEFINED;
-       }
-    }
-  if (!x && !a->addr[1] && !a->addr[2])
-    {
-      u32 y = a->addr[3];
-      if (y == 1)
-       return IADDR_HOST | SCOPE_HOST;         /* Loopback address */
-      /* IPv4 compatible addresses */
-      if (y >= 0x7f000000 && y < 0x80000000)
-       return IADDR_HOST | SCOPE_HOST;
-      if ((y & 0xff000000) == 0x0a000000 ||
-         (y & 0xffff0000) == 0xc0a80000 ||
-         (y & 0xfff00000) == 0xac100000)
-       return IADDR_HOST | SCOPE_SITE;
-      if (y >= 0x01000000 && y < 0xe0000000)
-       return IADDR_HOST | SCOPE_UNIVERSE;
-    }
-  return IADDR_HOST | SCOPE_UNDEFINED;
-}
-
-void
-ipv6_hton(ip_addr *a)
-{
-  int i;
-
-  for(i=0; i<4; i++)
-    a->addr[i] = htonl(a->addr[i]);
-}
-
-void
-ipv6_ntoh(ip_addr *a)
-{
-  int i;
-
-  for(i=0; i<4; i++)
-    a->addr[i] = ntohl(a->addr[i]);
-}
-
-int
-ipv6_compare(ip_addr X, ip_addr Y)
-{
-  int i;
-  ip_addr *x = &X;
-  ip_addr *y = &Y;
-
-  for(i=0; i<4; i++)
-    if (x->addr[i] > y->addr[i])
-      return 1;
-    else if (x->addr[i] < y->addr[i])
-      return -1;
-  return 0;
-}
-
-/*
- *  Conversion of IPv6 address to presentation format and vice versa.
- *  Heavily inspired by routines written by Paul Vixie for the BIND project
- *  and of course by RFC 2373.
- */
-
-char *
-ip_ntop(ip_addr a, char *b)
-{
-  u16 words[8];
-  int bestpos, bestlen, curpos, curlen, i;
-
-  /* First of all, preprocess the address and find the longest run of zeros */
-  bestlen = bestpos = curpos = curlen = 0;
-  for(i=0; i<8; i++)
-    {
-      u32 x = a.addr[i/2];
-      words[i] = ((i%2) ? x : (x >> 16)) & 0xffff;
-      if (words[i])
-       curlen = 0;
-      else
-       {
-         if (!curlen)
-           curpos = i;
-         curlen++;
-         if (curlen > bestlen)
-           {
-             bestpos = curpos;
-             bestlen = curlen;
-           }
-       }
-    }
-  if (bestlen < 2)
-    bestpos = -1;
-
-  /* Is it an encapsulated IPv4 address? */
-  if (!bestpos &&
-      (bestlen == 5 && a.addr[2] == 0xffff ||
-       bestlen == 6))
-    {
-      u32 x = a.addr[3];
-      b += bsprintf(b, "::%s%d.%d.%d.%d",
-                   a.addr[2] ? "ffff:" : "",
-                   ((x >> 24) & 0xff),
-                   ((x >> 16) & 0xff),
-                   ((x >> 8) & 0xff),
-                   (x & 0xff));
-      return b;
-    }
-
-  /* Normal IPv6 formatting, compress the largest sequence of zeros */
-  for(i=0; i<8; i++)
-    {
-      if (i == bestpos)
-       {
-         i += bestlen - 1;
-         *b++ = ':';
-         if (i == 7)
-           *b++ = ':';
-       }
-      else
-       {
-         if (i)
-           *b++ = ':';
-         b += bsprintf(b, "%x", words[i]);
-       }
-    }
-  *b = 0;
-  return b;
-}
-
-char *
-ip_ntox(ip_addr a, char *b)
-{
-  int i;
-
-  for(i=0; i<4; i++)
-    {
-      if (i)
-       *b++ = '.';
-      b += bsprintf(b, "%08x", a.addr[i]);
-    }
-  return b;
-}
-
-int
-ipv4_pton_u32(char *a, u32 *o)
-{
-  int i;
-  unsigned long int l;
-  u32 ia = 0;
-
-  i=4;
-  while (i--)
-    {
-      char *d, *c = strchr(a, '.');
-      if (!c != !i)
-       return 0;
-      l = strtoul(a, &d, 10);
-      if (d != c && *d || l > 255)
-       return 0;
-      ia = (ia << 8) | l;
-      if (c)
-       c++;
-      a = c;
-    }
-  *o = ia;
-  return 1;
-}
-
-int
-ip_pton(char *a, ip_addr *o)
-{
-  u16 words[8];
-  int i, j, k, l, hfil;
-  char *start;
-
-  if (a[0] == ':')                     /* Leading :: */
-    {
-      if (a[1] != ':')
-       return 0;
-      a++;
-    }
-  hfil = -1;
-  i = 0;
-  while (*a)
-    {
-      if (*a == ':')                   /* :: */
-       {
-         if (hfil >= 0)
-           return 0;
-         hfil = i;
-         a++;
-         continue;
-       }
-      j = 0;
-      l = 0;
-      start = a;
-      for(;;)
-       {
-         if (*a >= '0' && *a <= '9')
-           k = *a++ - '0';
-         else if (*a >= 'A' && *a <= 'F')
-           k = *a++ - 'A' + 10;
-         else if (*a >= 'a' && *a <= 'f')
-           k = *a++ - 'a' + 10;
-         else
-           break;
-         j = (j << 4) + k;
-         if (j >= 0x10000 || ++l > 4)
-           return 0;
-       }
-      if (*a == ':' && a[1])
-       a++;
-      else if (*a == '.' && (i == 6 || i < 6 && hfil >= 0))
-       {                               /* Embedded IPv4 address */
-         u32 x;
-         if (!ipv4_pton_u32(start, &x))
-           return 0;
-         words[i++] = x >> 16;
-         words[i++] = x;
-         break;
-       }
-      else if (*a)
-       return 0;
-      if (i >= 8)
-       return 0;
-      words[i++] = j;
-    }
-
-  /* Replace :: with an appropriate number of zeros */
-  if (hfil >= 0)
-    {
-      j = 8 - i;
-      for(i=7; i-j >= hfil; i--)
-       words[i] = words[i-j];
-      for(; i>=hfil; i--)
-       words[i] = 0;
-    }
-
-  /* Convert the address to ip_addr format */
-  for(i=0; i<4; i++)
-    o->addr[i] = (words[2*i] << 16) | words[2*i+1];
-  return 1;
-}
-
-void ipv6_absolutize(ip_addr *a, ip_addr *ifa)
-{
-  if ((a->addr[0] & 0xffc00000) == 0xfe800000 &&       /* a is link-scope */
-      ((ifa->addr[0] & 0xe0000000) == 0x20000000 |     /* ifa is AGU ... */
-       (ifa->addr[0] & 0xffc00000) == 0xfec00000))     /* ... or site-scope */
-    {
-      a->addr[0] = ifa->addr[0];       /* Copy the prefix, leave interface ID */
-      a->addr[1] = ifa->addr[1];
-    }
-}
-
-#ifdef TEST
-
-#include "bitops.c"
-
-static void test(char *x)
-{
-  ip_addr a;
-  char c[STD_ADDRESS_P_LENGTH+1];
-
-  printf("%-40s ", x);
-  if (!ip_pton(x, &a))
-    {
-      puts("BAD");
-      return;
-    }
-  ip_ntop(a, c);
-  printf("%-40s %04x\n", c, ipv6_classify(&a));
-}
-
-int main(void)
-{
-  puts("Positive tests:");
-  test("1:2:3:4:5:6:7:8");
-  test("dead:beef:DEAD:BEEF::f00d");
-  test("::");
-  test("::1");
-  test("1::");
-  test("::1.234.5.6");
-  test("::ffff:1.234.5.6");
-  test("::fffe:1.234.5.6");
-  test("1:2:3:4:5:6:7::8");
-  test("2080::8:800:200c:417a");
-  test("ff01::101");
-
-  puts("Negative tests:");
-  test(":::");
-  test("1:2:3:4:5:6:7:8:");
-  test("1::2::3");
-  test("::12345");
-  test("::1.2.3.4:5");
-  test(":1:2:3:4:5:6:7:8");
-  test("g:1:2:3:4:5:6:7");
-  return 0;
-}
-
-#endif
diff --git a/lib/ipv6.h b/lib/ipv6.h
deleted file mode 100644 (file)
index b935a6e..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-
-/*
- *     BIRD -- IP Addresses et Cetera for IPv6
- *
- *     (c) 1999--2000 Martin Mares <mj@ucw.cz>
- *
- *     Can be freely distributed and used under the terms of the GNU GPL.
- */
-
-#ifndef _BIRD_IPV6_H_
-#define _BIRD_IPV6_H_
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include "lib/string.h"
-#include "lib/bitops.h"
-#include "lib/unaligned.h"
-
-typedef struct ipv6_addr {
-  u32 addr[4];
-} ip_addr;
-
-#define _MI(a,b,c,d) ((struct ipv6_addr) {{ a, b, c, d }})
-#define _I0(a) ((a).addr[0])
-#define _I1(a) ((a).addr[1])
-#define _I2(a) ((a).addr[2])
-#define _I3(a) ((a).addr[3])
-
-#define MAX_PREFIX_LENGTH 128
-#define BITS_PER_IP_ADDRESS 128
-#define STD_ADDRESS_P_LENGTH 39
-#define SIZE_OF_IP_HEADER 40
-
-#define IPA_NONE _MI(0,0,0,0)
-
-#define ipa_equal(x,y)  ({ ip_addr _a=(x), _b=(y); \
-                          _I0(_a) == _I0(_b) && \
-                          _I1(_a) == _I1(_b) && \
-                          _I2(_a) == _I2(_b) && \
-                          _I3(_a) == _I3(_b); })
-#define ipa_nonzero(x) ({ ip_addr _a=(x); (_I0(_a) || _I1(_a) || _I2(_a) || _I3(_a)); })
-#define ipa_and(x,y) ({ ip_addr _a=(x), _b=(y); \
-                    _MI(_I0(_a) & _I0(_b), \
-                        _I1(_a) & _I1(_b), \
-                        _I2(_a) & _I2(_b), \
-                        _I3(_a) & _I3(_b)); })
-#define ipa_or(x,y)  ({ ip_addr _a=(x), _b=(y); \
-                    _MI(_I0(_a) | _I0(_b), \
-                        _I1(_a) | _I1(_b), \
-                        _I2(_a) | _I2(_b), \
-                        _I3(_a) | _I3(_b)); })
-#define ipa_xor(x,y) ({ ip_addr _a=(x), _b=(y); \
-                    _MI(_I0(_a) ^ _I0(_b), \
-                        _I1(_a) ^ _I1(_b), \
-                        _I2(_a) ^ _I2(_b), \
-                        _I3(_a) ^ _I3(_b)); })
-#define ipa_not(x) ({ ip_addr _a=(x); _MI(~_I0(_a),~_I1(_a),~_I2(_a),~_I3(_a)); })
-#define ipa_mkmask(x) ipv6_mkmask(x)
-#define ipa_mklen(x) ipv6_mklen(&(x))
-#define ipa_hash(x) ipv6_hash(&(x))
-#define ipa_hash32(x) ipv6_hash32(&(x))
-#define ipa_hton(x) ipv6_hton(&(x))
-#define ipa_ntoh(x) ipv6_ntoh(&(x))
-#define ipa_classify(x) ipv6_classify(&(x))
-#define ipa_has_link_scope(x) ipv6_has_link_scope(&(x))
-#define ipa_opposite_m1(x) ({ ip_addr _a=(x); _MI(_I0(_a),_I1(_a),_I2(_a),_I3(_a) ^ 1); })
-#define ipa_opposite_m2(x) ({ ip_addr _a=(x); _MI(_I0(_a),_I1(_a),_I2(_a),_I3(_a) ^ 3); })
-/* ipa_class_mask don't make sense with IPv6 */
-/* ipa_from_u32 and ipa_to_u32 replaced by ipa_build */
-#define ipa_build(a,b,c,d) _MI(a,b,c,d)
-#define ipa_compare(x,y) ipv6_compare(x,y)
-/* ipa_pxlen() requires that x != y */
-#define ipa_pxlen(x, y) ipv6_pxlen(x, y)
-#define ipa_getbit(x, y) ipv6_getbit(x, y)
-#define ipa_put_addr(x, y) ipv6_put_addr(x, y)
-#define ipa_absolutize(x,y) ipv6_absolutize(x,y)
-
-/* In IPv6, SOCK_RAW does not return packet header */
-#define ip_skip_header(x, y) x
-
-ip_addr ipv6_mkmask(unsigned);
-unsigned ipv6_mklen(ip_addr *);
-int ipv6_classify(ip_addr *);
-void ipv6_hton(ip_addr *);
-void ipv6_ntoh(ip_addr *);
-int ipv6_compare(ip_addr, ip_addr);
-int ipv4_pton_u32(char *, u32 *);
-void ipv6_absolutize(ip_addr *, ip_addr *);
-
-static inline int ipv6_has_link_scope(ip_addr *a)
-{
-  return ((a->addr[0] & 0xffc00000) == 0xfe800000);
-}
-
-/*
- *  This hash function looks well, but once IPv6 enters
- *  mainstream use, we need to check that it has good
- *  distribution properties on real routing tables.
- */
-
-static inline unsigned ipv6_hash(ip_addr *a)
-{
-  /* Returns a 16-bit hash key */
-  u32 x = _I0(*a) ^ _I1(*a) ^ _I2(*a) ^ _I3(*a);
-  return (x ^ (x >> 16) ^ (x >> 8)) & 0xffff;
-}
-
-static inline u32 ipv6_hash32(ip_addr *a)
-{
-  /* Returns a 32-bit hash key, although low-order bits are not ixed */
-  u32 x = _I0(*a) ^ _I1(*a) ^ _I2(*a) ^ _I3(*a);
-  return x ^ (x << 16) ^ (x << 24);
-}
-
-static inline u32 ipv6_getbit(ip_addr a, u32 y)
-{
-  return a.addr[y / 32] & (0x80000000 >> (y % 32));
-}
-
-static inline u32 ipv6_pxlen(ip_addr a, ip_addr b)
-{
-  int i = 0;
-  i+= (a.addr[i] == b.addr[i]);
-  i+= (a.addr[i] == b.addr[i]);
-  i+= (a.addr[i] == b.addr[i]);
-  i+= (a.addr[i] == b.addr[i]);
-  return 32 * i + 31 - u32_log2(a.addr[i] ^ b.addr[i]);
-}
-
-static inline byte * ipv6_put_addr(byte *buf, ip_addr a)
-{
-  put_u32(buf+0,  _I0(a));
-  put_u32(buf+4,  _I1(a));
-  put_u32(buf+8,  _I2(a));
-  put_u32(buf+12, _I3(a));
-  return buf+16;
-}
-
-#define IP_PREC_INTERNET_CONTROL 0xc0
-
-#endif
index ebecc14025deda0cf7799e1471523cfa048a9690..3eb988fa7a1fec7902b8658977552dadeada60c5 100644 (file)
@@ -283,9 +283,9 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
                /* IP address */
                case 'I':
                        if (flags & SPECIAL)
-                               ip_ntox(va_arg(args, ip_addr), ipbuf);
+                               ipa_ntox(va_arg(args, ip_addr), ipbuf);
                        else {
-                               ip_ntop(va_arg(args, ip_addr), ipbuf);
+                               ipa_ntop(va_arg(args, ip_addr), ipbuf);
                                if (field_width == 1)
                                        field_width = STD_ADDRESS_P_LENGTH;
                        }
index f1fffa948a562f796955f729d38761b3998ff2de..a5b85aa2c0b3f789be3c505c6fc5bf5a1e7d099d 100644 (file)
@@ -91,6 +91,8 @@ int sk_set_ipv6_checksum(sock *s, int offset);
 int sk_set_icmp6_filter(sock *s, int p1, int p2);
 void sk_log_error(sock *s, const char *p);
 
+byte * sk_rx_buffer(sock *s, int *len);        /* Temporary */
+
 extern int sk_priority_control;                /* Suggested priority for control traffic, should be sysdep define */
 
 
index 1d37bfd76b969befa270a8fc4f731bfee158da38..a091ed1e4013f2fd96f73373fbe748e42e9cc0d5 100644 (file)
@@ -991,7 +991,7 @@ bgp_create_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p
   if (p->cf->next_hop_self ||
       rta->dest != RTD_ROUTER ||
       ipa_equal(rta->gw, IPA_NONE) ||
-      ipa_has_link_scope(rta->gw) ||
+      ipa_is_link_local(rta->gw) ||
       (!p->is_internal && !p->cf->next_hop_keep &&
        (!p->neigh || (rta->iface != p->neigh->iface))))
     set_next_hop(z, p->source_addr);
index e2339112dbd79e97c528ea4b9f969f272abbe6e4..27825d7f1259d2531da4203fc34b9f2583b26161 100644 (file)
@@ -689,7 +689,7 @@ bgp_connect(struct bgp_proto *p)    /* Enter Connect state and start establishing c
   s->password = p->cf->password;
   s->tx_hook = bgp_connected;
   BGP_TRACE(D_EVENTS, "Connecting to %I%J from local address %I%J", s->daddr, p->cf->iface,
-           s->saddr, ipa_has_link_scope(s->saddr) ? s->iface : NULL);
+           s->saddr, ipa_is_link_local(s->saddr) ? s->iface : NULL);
   bgp_setup_conn(p, conn);
   bgp_setup_sk(conn, s);
   bgp_conn_set_state(conn, BS_CONNECT);
@@ -735,7 +735,7 @@ bgp_incoming_connection(sock *sk, int dummy UNUSED)
       {
        struct bgp_proto *p = (struct bgp_proto *) pc->proto;
        if (ipa_equal(p->cf->remote_ip, sk->daddr) &&
-           (!ipa_has_link_scope(sk->daddr) || (p->cf->iface == sk->iface)))
+           (!ipa_is_link_local(sk->daddr) || (p->cf->iface == sk->iface)))
          {
            /* We are in proper state and there is no other incoming connection */
            int acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
@@ -750,7 +750,7 @@ bgp_incoming_connection(sock *sk, int dummy UNUSED)
            }
 
            BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
-                     sk->daddr, ipa_has_link_scope(sk->daddr) ? sk->iface : NULL,
+                     sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL,
                      sk->dport, acc ? "accepted" : "rejected");
 
            if (!acc)
@@ -779,7 +779,7 @@ bgp_incoming_connection(sock *sk, int dummy UNUSED)
       }
 
   log(L_WARN "BGP: Unexpected connect from unknown address %I%J (port %d)",
-      sk->daddr, ipa_has_link_scope(sk->daddr) ? sk->iface : NULL, sk->dport);
+      sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL, sk->dport);
  reject:
   rfree(sk);
   return 0;
@@ -1169,8 +1169,8 @@ bgp_check_config(struct bgp_config *c)
   if (c->multihop && (c->gw_mode == GW_DIRECT))
     cf_error("Multihop BGP cannot use direct gateway mode");
 
-  if (c->multihop && (ipa_has_link_scope(c->remote_ip) || 
-                     ipa_has_link_scope(c->source_addr)))
+  if (c->multihop && (ipa_is_link_local(c->remote_ip) ||
+                     ipa_is_link_local(c->source_addr)))
     cf_error("Multihop BGP cannot be used with link-local addresses");
 
   if (c->multihop && c->bfd && ipa_zero(c->source_addr))
index 8e0b241261902e9428467f0cfae37166fadd876a..c834553043c490e4bce04f519e6262616cd55bcf 100644 (file)
@@ -63,7 +63,7 @@ bgp_proto:
  | bgp_proto NEIGHBOR ipa ipa_scope ipa_port AS expr ';' {
      if (ipa_nonzero(BGP_CFG->remote_ip))
        cf_error("Only one neighbor per BGP instance is allowed");
-     if (!ipa_has_link_scope($3) != !$4)
+     if (!ipa_is_link_local($3) != !$4)
        cf_error("Link-local address and interface scope must be used together");
 
      BGP_CFG->remote_ip = $3;
index 0b9de8c18a2103638f4f04f2fb56f03619116b99..69646c7dd18494d03a240462ab01e3297a7ddd92 100644 (file)
@@ -69,8 +69,8 @@ mrt_put_bgp4_hdr(byte *buf, struct bgp_conn *conn, int as4)
   put_u16(buf+0, (p->neigh && p->neigh->iface) ? p->neigh->iface->index : 0);
   put_u16(buf+2, BGP_AF);
   buf+=4;
-  buf = ipa_put_addr(buf, conn->sk ? conn->sk->daddr : IPA_NONE);
-  buf = ipa_put_addr(buf, conn->sk ? conn->sk->saddr : IPA_NONE);
+  buf = put_ipa(buf, conn->sk ? conn->sk->daddr : IPA_NONE);
+  buf = put_ipa(buf, conn->sk ? conn->sk->saddr : IPA_NONE);
 
   return buf;
 }
@@ -522,7 +522,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
          *tmp++ = BGP_AF_IPV6;
          *tmp++ = 1;
 
-         if (ipa_has_link_scope(ip))
+         if (ipa_is_link_local(ip))
            ip = IPA_NONE;
 
          if (ipa_nonzero(ip_ll))
@@ -1034,7 +1034,7 @@ bgp_set_next_hop(struct bgp_proto *p, rta *a)
   int second = (nh->u.ptr->length == NEXT_HOP_LENGTH) && ipa_nonzero(nexthop[1]);
 
   /* First address should not be link-local, but may be zero in direct mode */
-  if (ipa_has_link_scope(*nexthop))
+  if (ipa_is_link_local(*nexthop))
     *nexthop = IPA_NONE;
 #else
   int second = 0;
index 6df5df08f7eb1f5df726060e889dee0ea51fc1ce..e535287c682c762bf1bf7b68fadba64b0c91f340 100644 (file)
 #endif
 
 
-#define IP4_MIN_MTU            576
-#define IP6_MIN_MTU            1280
-
-#define IP4_OSPF_ALL_ROUTERS   ipa_build4(224, 0, 0, 5)
-#define IP4_OSPF_DES_ROUTERS   ipa_build4(224, 0, 0, 6)
-
-#define IP6_OSPF_ALL_ROUTERS   ipa_build6(0xFF020000, 0, 0, 5)
-#define IP6_OSPF_DES_ROUTERS   ipa_build6(0xFF020000, 0, 0, 6)
-
 #ifdef IPV6
-#define ip4_addr u32
-#define ip6_addr ip_addr
-#define _MI6(x1,x2,x3,x4) _MI(x1, x2, x3, x4)
-#define ipa_is_link_local(x) ipa_has_link_scope(x)
-#define ipa_from_u32(x) _MI6(0,0,0xffff,x)
-#define ipa_to_u32(x) _I3(x)
-#define ipa_build4(a,b,c,d) IPA_NONE
-#define ipa_build6(a,b,c,d) _MI6(a,b,c,d)
 #define OSPF_IS_V2 0
 #else
-#define ip4_addr u32
-#define ip6_addr ip_addr
-#define _I0(X) 0
-#define _I1(X) 0
-#define _I2(X) 0
-#define _I3(X) 0
-#define _MI6(x1,x2,x3,x4) IPA_NONE
-#define ipa_is_link_local(x) 0
-#define ipa_build4(a,b,c,d) _MI(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
-#define ipa_build6(a,b,c,d) IPA_NONE
 #define OSPF_IS_V2 1
 #endif
 
@@ -744,10 +717,12 @@ lsa_net_count(struct ospf_lsa_header *lsa)
 #define ipa_from_rid(x) ipa_from_u32(x)
 #define ipa_to_rid(x) ipa_to_u32(x)
 
-
 #define IPV6_PREFIX_SPACE(x) ((((x) + 63) / 32) * 4)
 #define IPV6_PREFIX_WORDS(x) (((x) + 63) / 32)
 
+/* FIXME: these four functions should be significantly redesigned w.r.t. integration,
+   also should be named as ospf3_* instead of *_ipv6_* */
+
 static inline u32 *
 lsa_get_ipv6_prefix(u32 *buf, ip_addr *addr, int *pxlen, u8 *pxopts, u16 *rest)
 {
@@ -787,6 +762,7 @@ lsa_get_ipv6_addr(u32 *buf, ip_addr *addr)
 static inline u32 *
 put_ipv6_prefix(u32 *buf, ip_addr addr, u8 pxlen, u8 pxopts, u16 lh)
 {
+#ifdef IPV6
   *buf++ = ((pxlen << 24) | (pxopts << 16) | lh);
 
   if (pxlen > 0)
@@ -797,6 +773,7 @@ put_ipv6_prefix(u32 *buf, ip_addr addr, u8 pxlen, u8 pxopts, u16 lh)
     *buf++ = _I2(addr);
   if (pxlen > 96)
     *buf++ = _I3(addr);
+#endif
   return buf;
 }
 
index 2814712d62ca53643166c9ce86bad560993087c0..a545c7fd7620df7532bcacdd6829fc506f1f60ef 100644 (file)
@@ -265,7 +265,8 @@ ospf_rx_hook(sock *sk, int len)
   }
 
   /* Second, we check packet length, checksum, and the protocol version */
-  struct ospf_packet *pkt = (struct ospf_packet *) ip_skip_header(sk->rbuf, &len);
+  struct ospf_packet *pkt = (void *) sk_rx_buffer(sk, &len);
+
 
   if (pkt == NULL)
     DROP("bad IP header", len);
index 08f90b491b49068617fb623e884d373ae0b667e1..b616c0d15a521eecc8d613d3f5cd5760d75a6270 100644 (file)
@@ -1822,10 +1822,10 @@ calc_next_hop(struct ospf_area *oa, struct top_hash_entry *en,
 
       struct ospf_lsa_link *llsa = lhe->lsa_body;
 
-      if (ipa_zero(llsa->lladdr))
+      if (ip6_zero(llsa->lladdr))
        return NULL;
 
-      return new_nexthop(p, llsa->lladdr, pn->iface, pn->weight);
+      return new_nexthop(p, ipa_from_ip6(llsa->lladdr), pn->iface, pn->weight);
     }
   }
 
index 15ba013a69f5da0eba47206a229a1e015785119e..42bf9c4555a60424c7df8b89ec3bc017c20a0ac4 100644 (file)
@@ -1319,7 +1319,7 @@ prepare_link_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
   ASSERT(p->lsab_used == 0);
   ll = lsab_allocz(p, sizeof(struct ospf_lsa_link));
   ll->options = ifa->oa->options | (ifa->priority << 24);
-  ll->lladdr = ifa->addr->ip;
+  ll->lladdr = ipa_to_ip6(ifa->addr->ip);
   ll = NULL; /* buffer might be reallocated later */
 
   struct ifa *a;
index ef8697224eb9725433718745aa74206ac0c61c59..3862af8d4ad8c5d4d1ed18a3ea6f48f97c664417 100644 (file)
@@ -343,7 +343,7 @@ radv_send_ra(struct radv_iface *ifa, int shutdown)
   }
 
   RADV_TRACE(D_PACKETS, "Sending RA via %s", ifa->iface->name);
-  sk_send_to(ifa->sk, ifa->plen, AllNodes, 0);
+  sk_send_to(ifa->sk, ifa->plen, IP6_ALL_NODES, 0);
 }
 
 
@@ -432,7 +432,7 @@ radv_sk_open(struct radv_iface *ifa)
   if (sk_setup_multicast(sk) < 0)
     goto err;
 
-  if (sk_join_group(sk, AllRouters) < 0)
+  if (sk_join_group(sk, IP6_ALL_ROUTERS) < 0)
     goto err;
 
   ifa->sk = sk;
index bb80d65fb9d4cd42fd6120cfa238bf25bf10d81f..48ba9c1a308df119b3953fd9a745faa5c85dd4ec 100644 (file)
@@ -26,9 +26,6 @@
 
 #define ICMPV6_PROTO 58
 
-#define AllNodes   _MI(0xFF020000, 0, 0, 1)    /* FF02::1 */
-#define AllRouters _MI(0xFF020000, 0, 0, 2)    /* FF02::2 */
-
 #define ICMPV6_RS 133
 #define ICMPV6_RA 134
 
index bc9ffc5f2667b1f60a7a7590f19da908e70fe6a7..a0c28e72fac3704ec1102f18af08aa36d165f515 100644 (file)
@@ -305,7 +305,7 @@ advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme, struct
   A.flags = 0;
 #ifndef IPV6
   A.gw = ipa_nonzero(b->nexthop) ? b->nexthop : whotoldme;
-  pxlen = ipa_mklen(b->netmask);
+  pxlen = ipa_masklen(b->netmask);
 #else
   /* FIXME: next hop is in other packet for v6 */
   A.gw = whotoldme; 
@@ -365,7 +365,7 @@ process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme, stru
 
 #ifndef IPV6
   metric = ntohl( block->metric );
-  pxlen = ipa_mklen(block->netmask);
+  pxlen = ipa_masklen(block->netmask);
 #else
   metric = block->metric;
   pxlen = block->pxlen;
@@ -447,7 +447,7 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
            ipa_ntoh( block->netmask );
            ipa_ntoh( block->nexthop );
            if (packet->heading.version == RIP_V1)      /* FIXME (nonurgent): switch to disable this? */
-             block->netmask = ipa_class_mask(block->network);
+             block->netmask = ip4_class_mask(ipa_to_ip4(block->network));
 #endif
            process_block( p, block, whotoldme, iface );
          }
@@ -721,7 +721,7 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
 #ifndef IPV6
       rif->sock->daddr = ipa_from_u32(0xe0000009);
 #else
-      rif->sock->daddr = ipa_build(0xff020000, 0, 0, 9);
+      rif->sock->daddr = IP6_RIP_ROUTERS;
 #endif
     } else {
       rif->sock->daddr = new->addr->brd;
@@ -812,7 +812,7 @@ rip_if_notify(struct proto *p, unsigned c, struct iface *iface)
 #ifndef IPV6
       lock->addr = ipa_from_u32(0xe0000009);
 #else
-      ip_pton("FF02::9", &lock->addr);
+      lock->addr = IP6_RIP_ROUTERS;
 #endif
     else
       lock->addr = iface->addr->brd;
index 621f7309fee55bf99d64eaae20041cdac25028a0..0e65c51c28fc4447640256a7a88503504215183e 100644 (file)
@@ -382,7 +382,7 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
   if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
     SKIP("strange class/scope\n");
 
-  int pxlen = (flags & RTF_HOST) ? MAX_PREFIX_LENGTH : ipa_mklen(imask);
+  int pxlen = (flags & RTF_HOST) ? MAX_PREFIX_LENGTH : ipa_masklen(imask);
   if (pxlen < 0)
     { log(L_ERR "%s (%I) - netmask %I", errmsg, idst, imask); return; }
 
@@ -653,7 +653,7 @@ krt_read_addr(struct ks_msg *msg, int scan)
   ibrd  = ipa_from_sa(&brd);
 
 
-  if ((masklen = ipa_mklen(imask)) < 0)
+  if ((masklen = ipa_masklen(imask)) < 0)
   {
     log(L_ERR "KIF: Invalid masklen %I for %s", imask, iface->name);
     return;
index 164038ec9a6de529eb3432059e23e25cecc14261..04f0fe505ea4b8a8e1abd664d03015ae3e2fa321 100644 (file)
@@ -764,6 +764,29 @@ sk_set_tos6(sock *s, int tos)
   return 0;
 }
 
+static inline byte *
+sk_skip_ip_header(byte *pkt, int *len)
+{
+  if ((*len < 20) || ((*pkt & 0xf0) != 0x40))
+    return NULL;
+
+  int hlen = (*pkt & 0x0f) * 4;
+  if ((hlen < 20) || (hlen > *len))
+    return NULL;
+
+  *len -= hlen;
+  return pkt + hlen;
+}
+
+byte *
+sk_rx_buffer(sock *s, int *len)
+{
+  if (sk_is_ipv4(s) && (s->type == SK_IP))
+    return sk_skip_ip_header(s->rbuf, len);
+  else
+    return s->rbuf;
+}
+
 
 /*
  *     Public socket functions
index 518713bc19d92c968b8a590943a7af06395ef2c4..3cee96b4cb8fbb73233f8464a9810e242dfc72cb 100644 (file)
@@ -47,19 +47,9 @@ typedef struct sockaddr_bird {
 
 #ifdef IPV6
 #define BIRD_AF AF_INET6
-#define _MI6(x1,x2,x3,x4) _MI(x1, x2, x3, x4)
-#define ipa_is_link_local(x) ipa_has_link_scope(x)
 #define ipa_from_sa(x) ipa_from_sa6(x)
-#define ipa_from_u32(x) _MI6(0,0,0xffff,x)
-#define ipa_to_u32(x) _I3(x)
 #else
 #define BIRD_AF AF_INET
-#define _I0(X) 0
-#define _I1(X) 0
-#define _I2(X) 0
-#define _I3(X) 0
-#define _MI6(x1,x2,x3,x4) IPA_NONE
-#define ipa_is_link_local(x) 0
 #define ipa_from_sa(x) ipa_from_sa4(x)
 #endif
 
@@ -75,7 +65,7 @@ static inline ip_addr ipa_from_in4(struct in_addr a)
 { return ipa_from_u32(ntohl(a.s_addr)); }
 
 static inline ip_addr ipa_from_in6(struct in6_addr a)
-{ return _MI6(ntohl(a.s6_addr32[0]), ntohl(a.s6_addr32[1]), ntohl(a.s6_addr32[2]), ntohl(a.s6_addr32[3])); }
+{ return ipa_build6(ntohl(a.s6_addr32[0]), ntohl(a.s6_addr32[1]), ntohl(a.s6_addr32[2]), ntohl(a.s6_addr32[3])); }
 
 static inline ip_addr ipa_from_sa4(sockaddr *sa)
 { return ipa_from_in4(((struct sockaddr_in *) sa)->sin_addr); }
@@ -86,8 +76,14 @@ static inline ip_addr ipa_from_sa6(sockaddr *sa)
 static inline struct in_addr ipa_to_in4(ip_addr a)
 { return (struct in_addr) { htonl(ipa_to_u32(a)) }; }
 
+#ifdef IPV6
 static inline struct in6_addr ipa_to_in6(ip_addr a)
 { return (struct in6_addr) { .s6_addr32 = { htonl(_I0(a)), htonl(_I1(a)), htonl(_I2(a)), htonl(_I3(a)) } }; }
+#else
+/* Temporary dummy */
+static inline struct in6_addr ipa_to_in6(ip_addr a)
+{ return (struct in6_addr) { .s6_addr32 = { 0, 0, 0, 0 } }; }
+#endif
 
 void sockaddr_fill(sockaddr *sa, int af, ip_addr a, struct iface *ifa, uint port);
 int sockaddr_read(sockaddr *sa, int af, ip_addr *a, struct iface **ifa, uint *port);