]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Temporary integrated commit.
authorOndrej Zajicek <santiago@crfreenet.org>
Fri, 22 Jun 2012 11:38:52 +0000 (13:38 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Fri, 22 Jun 2012 11:38:52 +0000 (13:38 +0200)
25 files changed:
conf/cf-lex.l
conf/conf.c
conf/confbase.Y
configure.in
filter/config.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
lib/unaligned.h
nest/config.Y
proto/radv/packets.c
proto/radv/radv.h
proto/rip/rip.c
sysdep/config.h
sysdep/linux/netlink.c
sysdep/linux/sysio.h
sysdep/unix/io.c
sysdep/unix/unix.h
tools/Makefile.in

index 8cd52c421fec854b6940f7862bc12c3eb677dc64..a46262274715eb8be876c6ed8e3224867fd78409 100644 (file)
@@ -106,25 +106,15 @@ include   ^{WHITE}*include{WHITE}*\".*\"{WHITE}*;
 {include} { if(cf_open_hook) new_include(); }
 
 {DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+ {
-#ifdef IPV6
-  if (ipv4_pton_u32(yytext, &cf_lval.i32))
-    return RTRID;
+  if (ip4_pton(yytext, &cf_lval.a4))
+    return IP4;
   cf_error("Invalid IPv4 address %s", yytext);
-#else
-  if (ip_pton(yytext, &cf_lval.a))
-    return IPA;
-  cf_error("Invalid IP address %s", yytext);
-#endif
 }
 
 ({XIGIT}*::|({XIGIT}*:){3,})({XIGIT}*|{DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+) {
-#ifdef IPV6
-  if (ip_pton(yytext, &cf_lval.a))
-    return IPA;
-  cf_error("Invalid IP address %s", yytext);
-#else
-  cf_error("This is an IPv4 router, therefore IPv6 addresses are not supported");
-#endif
+  if (ip6_pton(yytext, &cf_lval.a6))
+    return IP6;
+  cf_error("Invalid IPv6 address %s", yytext);
 }
 
 0x{XIGIT}+ {
index 13049be4512a1ac465cf66a0c56d4665596b3c11..47a0c0c1c9025dd747667095707b54f281f41422 100644 (file)
@@ -117,10 +117,11 @@ config_parse(struct config *c)
   protos_postconfig(c);
   if (EMPTY_LIST(c->protos))
     cf_error("No protocol is specified in the config file");
-#ifdef IPV6
+
+  /*
   if (!c->router_id)
-    cf_error("Router ID must be configured manually on IPv6 routers");
-#endif
+    cf_error("Router ID must be configured manually");
+  */
   return 1;
 }
 
index dcb0719f87599dde2827f38f340b19bdf03c9225..088c1e4f4ca19b79b650dc791af8e82e5ead201f 100644 (file)
@@ -39,6 +39,8 @@ CF_DECLS
   int i;
   u32 i32;
   ip_addr a;
+  ip4_addr a4;
+  ip6_addr a6;
   struct symbol *s;
   char *t;
   struct rtable_config *r;
@@ -67,14 +69,15 @@ CF_DECLS
 %token PO PC
 %token <i> NUM ENUM
 %token <i32> RTRID
-%token <a> IPA
+%token <a4> IP4
+%token <a6> IP6
 %token <s> SYM
 %token <t> TEXT
 %type <iface> ipa_scope
 
 %type <i> expr bool pxlen
 %type <time> datetime
-%type <a> ipa
+%type <a> ipa ipa_raw
 %type <px> prefix prefix_or_ipa
 %type <t> text_or_none
 
@@ -119,7 +122,7 @@ definition:
      cf_define_symbol($2, SYM_NUMBER, NULL);
      $2->aux = $4;
    }
- | DEFINE SYM '=' IPA ';' {
+ | DEFINE SYM '=' ipa_raw ';' {
      cf_define_symbol($2, SYM_IPA, cfg_alloc(sizeof(ip_addr)));
      *(ip_addr *)$2->def = $4;
    }
@@ -137,9 +140,15 @@ bool:
  ;
 
 /* Addresses, prefixes and netmasks */
+// XXXX check users
+
+ipa_raw:
+   IP4 { $$ = ipa_from_ip4($1); }
+ | IP6 { $$ = ipa_from_ip6($1); }
+ ;
 
 ipa:
-   IPA
+   ipa_raw
  | SYM {
      if ($1->class != SYM_IPA) cf_error("IP address expected");
      $$ = *(ip_addr *)$1->def;
index dd57ab513769a96fdb6b280abac6f68cc74d514e..2fa474a30eb71b95c49ecacd020872b79118ce42 100644 (file)
@@ -9,8 +9,6 @@ AC_CONFIG_AUX_DIR(tools)
 AC_ARG_ENABLE(debug,   [  --enable-debug          enable internal debugging routines (default: disabled)],,enable_debug=no)
 AC_ARG_ENABLE(memcheck,        [  --enable-memcheck       check memory allocations when debugging (default: enabled)],,enable_memcheck=yes)
 AC_ARG_ENABLE(client,  [  --enable-client         enable building of BIRD client (default: enabled)],,enable_client=yes)
-AC_ARG_ENABLE(ipv6,    [  --enable-ipv6           enable building of IPv6 version (default: disabled)],,enable_ipv6=no)
-AC_ARG_WITH(suffix,    [  --with-suffix=STRING    use specified suffix for BIRD files (default: 6 for IPv6 version)],[given_suffix="yes"])
 AC_ARG_WITH(sysconfig, [  --with-sysconfig=FILE   use specified BIRD system configuration file])
 AC_ARG_WITH(protocols, [  --with-protocols=LIST   include specified routing protocols (default: all)],,[with_protocols="all"])
 AC_ARG_WITH(sysinclude,        [  --with-sysinclude=PATH  search for system includes on specified place])
@@ -44,31 +42,19 @@ AC_SUBST(exedir)
 AC_SUBST(srcdir_rel_mf)
 AC_SUBST(runtimedir)
 
-if test "$enable_ipv6" = yes ; then
-       ip=ipv6
-       SUFFIX=6
-       all_protocols=bgp,ospf,pipe,radv,rip,static
-else
-       ip=ipv4
-       SUFFIX=""
-       all_protocols=bgp,ospf,pipe,rip,static
-fi
-
-if test "$given_suffix" = yes ; then
-       SUFFIX="$with_suffix"
-fi
-AC_SUBST(SUFFIX)
+# all_protocols=bgp,ospf,pipe,radv,rip,static
+all_protocols=pipe,radv,rip,static
 
 if test "$with_protocols" = all ; then
        with_protocols="$all_protocols"
 fi
 
 if test "$enable_debug" = yes ; then
-       CONFIG_FILE="bird$SUFFIX.conf"
-       CONTROL_SOCKET="bird$SUFFIX.ctl"
+       CONFIG_FILE="bird.conf"
+       CONTROL_SOCKET="bird.ctl"
 else
-       CONFIG_FILE="\$(sysconfdir)/bird$SUFFIX.conf"
-       CONTROL_SOCKET="$runtimedir/bird$SUFFIX.ctl"
+       CONFIG_FILE="\$(sysconfdir)/bird.conf"
+       CONTROL_SOCKET="$runtimedir/bird.ctl"
 fi
 AC_SUBST(CONFIG_FILE)
 AC_SUBST(CONTROL_SOCKET)
@@ -123,32 +109,19 @@ if test -n "$with_sysconfig" -a "$with_sysconfig" != no ; then
 elif test -f sysconfig.h ; then
        sysdesc=sysconfig
 else
-       case "$ip:$host_os" in
-               ipv6:linux*)    sysdesc=linux-v6
+       case "$host_os" in
+               linux*)         sysdesc=linux
                                default_iproutedir="/etc/iproute2"
                                ;;
-               ipv4:linux*)    sysdesc=linux
-                               default_iproutedir="/etc/iproute2"
+               freebsd*)       sysdesc=bsd
                                ;;
-               ipv6:netbsd*)   sysdesc=bsd-v6
-                               CPPFLAGS="$CPPFLAGS -I/usr/pkg/include"
-                               LDFLAGS="$LDFLAGS -L/usr/pkg/lib -R/usr/pkg/lib"
+               kfreebsd*)      sysdesc=bsd
                                ;;
-               ipv4:netbsd*)   sysdesc=bsd
+               netbsd*)        sysdesc=bsd
                                CPPFLAGS="$CPPFLAGS -I/usr/pkg/include"
                                LDFLAGS="$LDFLAGS -L/usr/pkg/lib -R/usr/pkg/lib"
                                ;;
-               ipv6:freebsd*)  sysdesc=bsd-v6
-                               ;;
-               ipv4:freebsd*)  sysdesc=bsd
-                               ;;
-               ipv6:kfreebsd*) sysdesc=bsd-v6
-                               ;;
-               ipv4:kfreebsd*) sysdesc=bsd
-                               ;;
-               ipv6:openbsd*)  sysdesc=bsd-v6
-                               ;;
-               ipv4:openbsd*)  sysdesc=bsd
+               openbsd*)       sysdesc=bsd
                                ;;
                *)              AC_MSG_ERROR([Cannot determine correct system configuration. Please use --with-sysconfig to set it manually.])
                                ;;
index 0eeb2ce1748b77ad60f6495c38db245d579ed0e1..ea4ca9d1842ef5349731eba97ff069dde8516b05 100644 (file)
@@ -452,7 +452,7 @@ block:
  * Complex types, their bison value is struct f_val
  */
 fipa:
-   IPA %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.px.ip = $1; }
+   ipa_raw %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.px.ip = $1; }
  ;
 
 
@@ -541,7 +541,7 @@ switch_items:
  ;
 
 fprefix_s:
-   IPA '/' NUM %prec '/' {
+   ipa_raw '/' NUM %prec '/' {
      if (($3 < 0) || ($3 > MAX_PREFIX_LENGTH) || !ip_is_prefix($1, $3)) cf_error("Invalid network prefix: %I/%d.", $1, $3);
      $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3;
    }
index c585c9a845ee287686f95ff959cb16a0b9221146..01c9db7f9df736835d3e741613c418d39950e341 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..3c959fea6ada36362eafb3d50c15403b5ad2e2a6 100644 (file)
--- a/lib/ip.c
+++ b/lib/ip.c
@@ -6,6 +6,8 @@
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 
+#include <stdlib.h>
+
 #include "nest/bird.h"
 #include "lib/ip.h"
 
  * they must be manipulated using the following functions and macros.
  */
 
+
+
+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(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
+ip6_masklen(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
+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 */
+    {
+      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])
+    {
+      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)
@@ -35,6 +349,9 @@ ip_scope_text(unsigned scope)
     return scope_table[scope];
 }
 
+
+
+
 #if 0
 /**
  * ipa_equal - compare two IP addresses for equality
@@ -193,7 +510,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 +520,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..706bbcf5880ec5f6b8d3ea8237e9ad40f3e1a471 100644 (file)
--- a/lib/ip.h
+++ b/lib/ip.h
@@ -9,32 +9,70 @@
 #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"
+
+
+#ifdef DEBUGGING
+
+/*
+ *     Use the structural representation when you want to make sure
+ *     nobody unauthorized attempts to handle ip_addr as number.
+ */
+
+typedef struct ip4_addr {
+  u32 addr;
+} ip4_addr;
+
+#define _MI4(x) ((struct ip4_addr) { x })
+#define _I(x) (x).addr
+
 #else
-#include "ipv6.h"
+
+typedef u32 ip4_addr;
+
+#define _MI4(x) (x)
+#define _I(x) (x)
+
 #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)))))
+
+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])
+
+
+typedef ip6_addr ip_addr;
+
+
+
+#define IPA_NONE IP6_NONE
+#define IP4_NONE _MI4(0)
+#define IP6_NONE _MI6(0,0,0,0)
+
 
 /*
  *     ip_classify() returns either a negative number for invalid addresses
  *     or scope OR'ed together with address type.
  */
-
 #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_UNIVERSE 4
 #define SCOPE_UNDEFINED 5
 
-char *ip_scope_text(unsigned);
+
+
+#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)
+
+#define ip4_equal(x,y) (_I(x) == _I(y))
+#define ip4_zero(x) (!_I(x))
+#define ip4_nonzero(x) _I(x)
+#define ip4_and(x,y) _MI4(_I(x) & _I(y))
+#define ip4_or(x,y) _MI4(_I(x) | _I(y))
+#define ip4_xor(x,y) _MI4(_I(x) ^ _I(y))
+#define ip4_not(x) _MI4(~_I(x))
+
+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)); }
+
+
+
+#define ipa_from_ip4(x) _MI6(0,0,0xffff,_I(x))
+#define ipa_from_ip6(x) x
+
+#define ipa_to_ip4(x) _I3(x)
+#define ipa_to_ip6(x) x
+
+#define ip4_from_u32(x) _MI4(x)
+#define ip4_to_u32(x) _I(x)
+
+#define ipa_is_ip4(a) ip6_is_v4mapped(a)
+
+#define ipa_build4(a,b,c,d) ipa_from_ip4(ip4_build(a,b,c,d))
+#define ipa_build6(a,b,c,d) _MI6(a,b,c,d)
+
+#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_hton(x) x = ip6_hton(x)
+#define ipa_ntoh(x) x = ip6_ntoh(x)
+
+#define ip4_hton(x) _MI4(htonl(_I(x)))
+#define ip4_ntoh(x) _MI4(ntohl(_I(x)))
+
+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))); }
+
+
+
+#define ipa_compare(a,b) ip6_compare(a,b)
+
+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);
+
+
+
+#define ipa_hash(a) ip6_hash(a)
+
+static inline unsigned ip4_hash(ip4_addr a)
+{
+  /* Returns a 16-bit value */
+  u32 x = _I(a);
+  x ^= x >> 16;
+  x ^= x << 10;
+  return x & 0xffff;
+}
 
 /*
- *     Network prefixes
+ *  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 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;
+}
+
+
+#define ipa_classify(x) ip6_classify(&(x))
+int ip4_classify(ip4_addr ad);
+int ip6_classify(ip6_addr *a);
+
+#define ipa_is_link_local(a) ip6_is_link_local(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; }
+
+
+
+#define ipa_mkmask(x) ip6_mkmask(x)
+#define ipa_mklen(x) ip6_masklen(&x)   // XXXX: ipa_masklen()
+
+#define ip4_mkmask(x) _MI4(u32_mkmask(x))
+#define ip4_masklen(x) u32_masklen(_I(x))
+
+ip6_addr ip6_mkmask(unsigned n);
+unsigned ip6_masklen(ip_addr *a);      // XXXX: int or unsigned?
+
+
+
+/* ipa_pxlen() requires that x != y */
+#define ipa_pxlen(a,b) ip6_pxlen(a,b)
+
+static inline u32 ip4_pxlen(ip4_addr a, ip4_addr b)
+{ return 31 - u32_log2(_I(a) ^ _I(b)); }
+
+static inline u32 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]);
+}
+
+
+
+#define ipa_opposite_m1(x) ip6_opposite_m1(x)
+#define ipa_opposite_m2(x) ip6_opposite_m2(x)
+
+#define ip4_opposite_m1(x) _MI4(_I(x) ^ 1)
+#define ip4_opposite_m2(x) _MI4(_I(x) ^ 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); }
+
+
+
+// XXXX
+#define ipa_getbit(a,y) ip6_getbit(a,y) 
+
+static inline u32 ip4_getbit(ip4_addr a, u32 pos)
+{ return _I(a) & (0x80000000 >> pos); }
+
+static inline u32 ip6_getbit(ip6_addr a, u32 pos)
+{ return a.addr[pos / 32] & (0x80000000 >> (pos % 32)); }
+
+
+// XXXX
+#define ipa_put_addr(buf,a) ip6_put(buf,a)
+
+static inline void * ip4_put(void *buf, ip4_addr a)
+{
+  put_u32(buf, _I(a));
+  return buf+4;
+}
+
+static inline void * ip6_put(void *buf, ip6_addr a)
+{
+  a = ip6_hton(a);
+  memcpy(buf, &a, 16);
+  return buf+16;
+}
+
+static inline ip4_addr ip4_get(void *buf)
+{
+  return _MI4(get_u32(buf));
+}
+
+static inline ip6_addr ip6_get(void *buf)
+{
+  ip6_addr a;
+  memcpy(&a, buf, 16);
+  return ip6_ntoh(a);
+}
+
+static inline void * ip4_put32(void *buf, ip4_addr a)
+{
+  *(u32 *)buf = htonl(_I(a));
+  return buf+4;
+}
+
+static inline void * ip6_put32(void *buf, ip6_addr a)
+{
+  u32 *b = buf;
+  b[0] = htonl(_I0(a));
+  b[1] = htonl(_I1(a));
+  b[2] = htonl(_I2(a));
+  b[3] = htonl(_I3(a));
+  return buf+16;
+}
+
+static inline void * ip6_put32_ip4(void *buf, ip6_addr a)
+{
+  *(u32 *)buf = htonl(_I3(a));
+  return buf+4;
+}
+
+static inline ip6_addr ipa_get_in4(struct in_addr *in)
+{ return ipa_from_ip4(ip4_ntoh(*(ip4_addr *) in)); }
+
+static inline ip6_addr ipa_get_in6(struct in6_addr *in)
+{ return ip6_ntoh(*(ip6_addr *) in); }
+
+// XXXX check callers
+static inline void ipa_put_in4(struct in_addr *in, ip6_addr a)
+{ ip6_put32_ip4(in, a); }
+
+static inline void ipa_put_in6(struct in6_addr *in, ip6_addr a)
+{ ip6_put32(in, a); }
+
+
+
+/*
+ *     Conversions between internal and string representation
  */
 
+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 process rest
+
 struct prefix {
   ip_addr addr;
   unsigned int len;
 };
 
+#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);
+
+/*
+ *     Network prefixes
+ */
+
 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
- */
+#define MAX_PREFIX_LENGTH 32
+#define BITS_PER_IP_ADDRESS 32
+#define STD_ADDRESS_P_LENGTH 15
+#define SIZE_OF_IP_HEADER 24
+*/
+
+
+
+#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_class_mask(x) _MI4(ipv4_class_mask(_I(x)))
+
+
+/*
+#define ip_skip_header(x, y) ipv4_skip_header(x, y)
 
-char *ip_ntop(ip_addr a, char *);
-char *ip_ntox(ip_addr a, char *);
-int ip_pton(char *a, ip_addr *o);
+#define IP_PREC_INTERNET_CONTROL 0xc0
+*/
+
+u32 ipv4_class_mask(u32);
+byte *ipv4_skip_header(byte *, int *);
+
+
+
+
+
+/* In IPv6, SOCK_RAW does not return packet header */
+#define ip_skip_header(x, y) x
+
+
+/*
+ *  RFC 1883 defines packet precendece, but RFC 2460 replaces it
+ *  by generic Traffic Class ID with no defined semantics. Better
+ *  not use it yet.
+ */
+#define IP_PREC_INTERNET_CONTROL -1
 
 #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 f258d37..0000000
+++ /dev/null
@@ -1,107 +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_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 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 6f8e7b3..0000000
+++ /dev/null
@@ -1,138 +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_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_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;
-}
-
-/*
- *  RFC 1883 defines packet precendece, but RFC 2460 replaces it
- *  by generic Traffic Class ID with no defined semantics. Better
- *  not use it yet.
- */
-#define IP_PREC_INTERNET_CONTROL -1
-
-#endif
index 14af10629ffe44b4aac1e303050f0df56dfa0e42..562844b32922fa41b8974e7745b49b3b3da65745 100644 (file)
@@ -273,9 +273,10 @@ 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);
+                               ip6_ntox(va_arg(args, ip_addr), ipbuf);
                        else {
-                               ip_ntop(va_arg(args, ip_addr), ipbuf);
+                               // XXXX update IPv4 / IPv6 distinction
+                               ip6_ntop(va_arg(args, ip_addr), ipbuf);
                                if (field_width > 0)
                                        field_width = STD_ADDRESS_P_LENGTH;
                        }
@@ -300,11 +301,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
                /* Router/Network ID - essentially IPv4 address in u32 value */
                case 'R':
                        x = va_arg(args, u32);
-                       bsprintf(ipbuf, "%d.%d.%d.%d",
-                                ((x >> 24) & 0xff),
-                                ((x >> 16) & 0xff),
-                                ((x >> 8) & 0xff),
-                                (x & 0xff));
+                       ip4_ntop(ip4_from_u32(x), ipbuf);
                        s = ipbuf;
                        goto str;
 
index b0c3eda2c20f0b37ae091fc602478a8184f5f2b3..618e69b844ac2e999a49588da1efdbbc96c81251 100644 (file)
@@ -43,6 +43,7 @@ typedef struct birdsock {
   /* laddr and lifindex are valid only if SKF_LADDR_RX flag is set to request it */
 
   int fd;                              /* System-dependent data */
+  int af;                              /* Address family (AF_INET, AF_INET6 or 0 for non-IP) of fd */
   node n;
   void *rbuf_alloc, *tbuf_alloc;
   char *password;                              /* Password for MD5 authentication */
@@ -66,25 +67,27 @@ int sk_setup_multicast(sock *s);
 int sk_join_group(sock *s, ip_addr maddr);
 int sk_leave_group(sock *s, ip_addr maddr);
 
-#ifdef IPV6
 int sk_set_ipv6_checksum(sock *s, int offset);
-int sk_set_icmp_filter(sock *s, int p1, int p2);
-#endif
-
+int sk_set_icmp6_filter(sock *s, int p1, int p2);
 int sk_set_broadcast(sock *s, int enable);
 
-static inline int
-sk_send_buffer_empty(sock *sk)
-{
-       return sk->tbuf == sk->tpos;
-}
+static inline int sk_send_buffer_empty(sock *sk)
+{ return sk->tbuf == sk->tpos; }
+
+static inline int sk_is_ipv4(sock *sk)
+{ return sk->af == AF_INET; }
+
+static inline int sk_is_ipv6(sock *sk)
+{ return sk->af == AF_INET6; }
+
 
 
 /* Socket flags */
 
-#define SKF_V6ONLY     1       /* Use IPV6_V6ONLY socket option */
-#define SKF_LADDR_RX   2       /* Report local address for RX packets */
-#define SKF_LADDR_TX   4       /* Allow to specify local address for TX packets */
+#define SKF_V4ONLY     1       /* Use IPv4 for IP sockets */
+#define SKF_V6ONLY     2       /* Use IPV6_V6ONLY socket option */
+#define SKF_LADDR_RX   4       /* Report local address for RX packets */
+#define SKF_LADDR_TX   6       /* Allow to specify local address for TX packets */
 
 
 /*
index af6552046830df3316d0724c4efba35519a9456e..1f418cd9ae0c8273993d3f32d4f6e36fcea0be58 100644 (file)
@@ -17,6 +17,7 @@
  *  if possible.
  */
 
+#include "lib/endian.h"
 #include "lib/string.h"
 
 static inline u16
index 14cff10a4c90c9621ee8d65b11f4a2e006be8135..420f0213be3f5fd129617157be2cf5f2e4debe7c 100644 (file)
@@ -46,7 +46,7 @@ CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OF
 CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
 CF_KEYWORDS(LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE)
 CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
-CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, MAX, FLUSH)
+CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, AS, MAX, FLUSH)
 CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
 CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC)
 
@@ -82,14 +82,7 @@ rtrid: ROUTER ID idval ';' {
 
 idval:
    NUM { $$ = $1; }
- | RTRID
- | IPA {
-#ifndef IPV6
-     $$ = ipa_to_u32($1);
-#else
-     cf_error("Router IDs must be entered as hexadecimal numbers or IPv4 addresses in IPv6 version");
-#endif
-   }
+ | IP4 { $$ = ip4_to_u32($1);  }
  ;
 
 
index ac59ce9436dca14451e4cba10aeee59f712faef5..a87b96891a7d85a467558bce0094ad742aae6eb8 100644 (file)
@@ -245,7 +245,7 @@ radv_sk_open(struct radv_iface *ifa)
   sk->saddr = ifa->addr->ip;
 
   /* We want listen just to ICMPv6 messages of type RS and RA */
-  if (sk_set_icmp_filter(sk, ICMPV6_RS, ICMPV6_RA) < 0)
+  if (sk_set_icmp6_filter(sk, ICMPV6_RS, ICMPV6_RA) < 0)
     goto err;
 
   if (sk_setup_multicast(sk) < 0)
index 12bfe42e5104d8b5a69ebe579d33280c635bc296..3f88eac886bd17469e6b3214efa2bfb8cb1a91cb 100644 (file)
@@ -26,8 +26,8 @@
 
 #define ICMPV6_PROTO 58
 
-#define AllNodes   _MI(0xFF020000, 0, 0, 1)    /* FF02::1 */
-#define AllRouters _MI(0xFF020000, 0, 0, 2)    /* FF02::2 */
+#define AllNodes   ipa_build6(0xFF020000, 0, 0, 1)     /* FF02::1 */
+#define AllRouters ipa_build6(0xFF020000, 0, 0, 2)     /* FF02::2 */
 
 #define ICMPV6_RS 133
 #define ICMPV6_RA 134
index 281296a50a0450a762380fca5f1aea26396a6844..9ec4ac749e8c7c2c02bbc2265921f5217921590b 100644 (file)
@@ -718,7 +718,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 = ipa_build6(0xff020000, 0, 0, 9);
 #endif
     } else {
       rif->sock->daddr = new->addr->brd;
@@ -808,7 +808,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 = ipa_build6(0xff020000, 0, 0, 9);
 #endif
     else
       lock->addr = iface->addr->brd;
index 8d93d3811ab492d669bf2bb6b09405ca8aa2fa02..c015438744b0967fd3983aa575f900f442a91cdf 100644 (file)
@@ -9,6 +9,9 @@
 /* BIRD version */
 #define BIRD_VERSION "1.3.7"
 
+// XXXX temporary define
+#define IPV1 1
+
 /* Include parameters determined by configure script */
 #include "sysdep/autoconf.h"
 
index eaaf048e1c41bfefce93ca21b2a2fa404da5d434..2c511519042ba125d676d0de37de97a9c2dca0b6 100644 (file)
@@ -94,7 +94,7 @@ nl_send(struct nl_sock *nl, struct nlmsghdr *nh)
 }
 
 static void
-nl_request_dump(int cmd)
+nl_request_dump(int pf, int cmd)
 {
   struct {
     struct nlmsghdr nh;
@@ -103,9 +103,7 @@ nl_request_dump(int cmd)
   req.nh.nlmsg_type = cmd;
   req.nh.nlmsg_len = sizeof(req);
   req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
-  /* Is it important which PF_* is used for link-level interface scan?
-     It seems that some information is available only when PF_INET is used. */
-  req.g.rtgen_family = (cmd == RTM_GETLINK) ? PF_INET : BIRD_PF;
+  req.g.rtgen_family = pf;
   nl_send(&nl_scan, &req.nh);
 }
 
@@ -239,6 +237,19 @@ nl_parse_attrs(struct rtattr *a, struct rtattr **k, int ksize)
     return 1;
 }
 
+static inline ip4_addr rta4_get_ip4(struct rtattr *a)
+{ return ip4_get(RTA_DATA(a)); }
+
+static inline ip6_addr rta6_get_ip6(struct rtattr *a)
+{ return ip6_get(RTA_DATA(a)); }
+
+static inline ip_addr rta4_get_ipa(struct rtattr *a)
+{ return ipa_from_ip4(ip4_get(RTA_DATA(a))); }
+
+static inline ip_addr rta6_get_ipa(struct rtattr *a)
+{ return ipa_from_ip6(ip6_get(RTA_DATA(a))); }
+
+
 void
 nl_add_attr(struct nlmsghdr *h, unsigned bufsize, unsigned code,
            void *data, unsigned dlen)
@@ -445,54 +456,58 @@ nl_parse_addr(struct nlmsghdr *h)
 {
   struct ifaddrmsg *i;
   struct rtattr *a[IFA_ANYCAST+1];
-  int new = h->nlmsg_type == RTM_NEWADDR;
+  int new = (h->nlmsg_type == RTM_NEWADDR);
   struct ifa ifa;
-  struct iface *ifi;
-  int scope;
+  ip_addr addr;
+  int ipv4 = 0;
 
   if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFA_RTA(i), a, sizeof(a)))
     return;
-  if (i->ifa_family != BIRD_AF)
-    return;
-  if (!a[IFA_ADDRESS] || RTA_PAYLOAD(a[IFA_ADDRESS]) != sizeof(ip_addr)
-#ifdef IPV6
-      || a[IFA_LOCAL] && RTA_PAYLOAD(a[IFA_LOCAL]) != sizeof(ip_addr)
-#else
-      || !a[IFA_LOCAL] || RTA_PAYLOAD(a[IFA_LOCAL]) != sizeof(ip_addr)
-      || (a[IFA_BROADCAST] && RTA_PAYLOAD(a[IFA_BROADCAST]) != sizeof(ip_addr))
-#endif
-      )
+
+  bzero(&ifa, sizeof(ifa));
+
+  if (i->ifa_family == AF_INET)
     {
-      log(L_ERR "nl_parse_addr: Malformed message received");
-      return;
+      if (!a[IFA_ADDRESS] || (RTA_PAYLOAD(a[IFA_ADDRESS]) != sizeof(ip4_addr)) ||
+         !a[IFA_LOCAL]   || (RTA_PAYLOAD(a[IFA_LOCAL]) != sizeof(ip4_addr)))
+       goto malformed;
+
+      addr = rta4_get_ipa(a[IFA_ADDRESS]);
+      ifa.ip = rta4_get_ipa(a[IFA_LOCAL]);
+      ipv4 = 1;
     }
+  else if (i->ifa_family == AF_INET6)
+    {
+      if (!a[IFA_ADDRESS] || (RTA_PAYLOAD(a[IFA_ADDRESS]) != sizeof(ip6_addr)) ||
+         (a[IFA_LOCAL]   && (RTA_PAYLOAD(a[IFA_LOCAL]) != sizeof(ip6_addr))))
+       goto malformed;
+
+      addr = rta6_get_ipa(a[IFA_ADDRESS]);
+      /* IFA_LOCAL can be unset for IPv6 interfaces */
+      ifa.ip = a[IFA_LOCAL] ? rta6_get_ipa(a[IFA_LOCAL]) : addr;
+    }
+  else
+    return;    /* Ignore unknown address families */
 
-  ifi = if_find_by_index(i->ifa_index);
-  if (!ifi)
+  ifa.iface = if_find_by_index(i->ifa_index);
+  if (!ifa.iface)
     {
       log(L_ERR "KIF: Received address message for unknown interface %d", i->ifa_index);
       return;
     }
 
-  bzero(&ifa, sizeof(ifa));
-  ifa.iface = ifi;
   if (i->ifa_flags & IFA_F_SECONDARY)
     ifa.flags |= IA_SECONDARY;
 
-  /* IFA_LOCAL can be unset for IPv6 interfaces */
-  memcpy(&ifa.ip, RTA_DATA(a[IFA_LOCAL] ? : a[IFA_ADDRESS]), sizeof(ifa.ip));
-  ipa_ntoh(ifa.ip);
-  ifa.pxlen = i->ifa_prefixlen;
-  if (i->ifa_prefixlen > BITS_PER_IP_ADDRESS)
+  ifa.pxlen = i->ifa_prefixlen + (ipv4 ? 96 : 0); // XXXXX: Hack
+  if (ifa.pxlen > BITS_PER_IP_ADDRESS)
     {
-      log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen);
-      new = 0;
+      log(L_ERR "KIF: Received invalid pxlen %d on %s",  i->ifa_prefixlen, ifa.iface->name);
+      return;
     }
+
   if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS)
     {
-      ip_addr addr;
-      memcpy(&addr, RTA_DATA(a[IFA_ADDRESS]), sizeof(addr));
-      ipa_ntoh(addr);
       ifa.prefix = ifa.brd = addr;
 
       /* It is either a host address or a peer address */
@@ -507,44 +522,36 @@ nl_parse_addr(struct nlmsghdr *h)
   else
     {
       ip_addr netmask = ipa_mkmask(ifa.pxlen);
-      ifa.prefix = ipa_and(ifa.ip, netmask);
-      ifa.brd = ipa_or(ifa.ip, ipa_not(netmask));
+      ifa.prefix = ipa_and(addr, netmask);
+      ifa.brd = ipa_or(addr, ipa_not(netmask));
+
       if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 1)
        ifa.opposite = ipa_opposite_m1(ifa.ip);
 
-#ifndef IPV6
-      if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 2)
+      if ((i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 2) && ipv4)
        ifa.opposite = ipa_opposite_m2(ifa.ip);
-
-      if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST])
-       {
-         ip_addr xbrd;
-         memcpy(&xbrd, RTA_DATA(a[IFA_BROADCAST]), sizeof(xbrd));
-         ipa_ntoh(xbrd);
-         if (ipa_equal(xbrd, ifa.prefix) || ipa_equal(xbrd, ifa.brd))
-           ifa.brd = xbrd;
-         else if (ifi->flags & IF_TMP_DOWN) /* Complain only during the first scan */
-           log(L_ERR "KIF: Invalid broadcast address %I for %s", xbrd, ifi->name);
-       }
-#endif
     }
 
-  scope = ipa_classify(ifa.ip);
-  if (scope < 0)
+  int scope = ipa_classify(ifa.ip);
+  if ((scope == IADDR_INVALID) || !(scope & IADDR_HOST))
     {
-      log(L_ERR "KIF: Invalid interface address %I for %s", ifa.ip, ifi->name);
+      log(L_ERR "KIF: Received invalid address %I on %s", ifa.ip, ifa.iface->name);
       return;
     }
   ifa.scope = scope & IADDR_SCOPE_MASK;
 
   DBG("KIF: IF%d(%s): %s IPA %I, flg %x, net %I/%d, brd %I, opp %I\n",
-      ifi->index, ifi->name,
-      new ? "added" : "removed",
+      ifa.iface->index, ifa.iface->name, new ? "added" : "removed",
       ifa.ip, ifa.flags, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite);
   if (new)
     ifa_update(&ifa);
   else
     ifa_delete(&ifa);
+  return;
+
+ malformed:
+  log(L_ERR "KIF: Received malformed address message");
+  return;
 }
 
 void
@@ -554,14 +561,24 @@ kif_do_scan(struct kif_proto *p UNUSED)
 
   if_start_update();
 
-  nl_request_dump(RTM_GETLINK);
+  /* Is it important which PF_* is used for link-level interface scan?
+     It seems that some information is available only when PF_INET is used. */
+
+  nl_request_dump(PF_INET, RTM_GETLINK);
   while (h = nl_get_scan())
     if (h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)
       nl_parse_link(h, 1);
     else
       log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
 
-  nl_request_dump(RTM_GETADDR);
+  nl_request_dump(PF_INET, RTM_GETADDR);
+  while (h = nl_get_scan())
+    if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
+      nl_parse_addr(h);
+    else
+      log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
+
+  nl_request_dump(PF_INET6, RTM_GETADDR);
   while (h = nl_get_scan())
     if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
       nl_parse_addr(h);
@@ -944,7 +961,7 @@ krt_do_scan(struct krt_proto *p UNUSED)     /* CONFIG_ALL_TABLES_AT_ONCE => p is NUL
 {
   struct nlmsghdr *h;
 
-  nl_request_dump(RTM_GETROUTE);
+  nl_request_dump(BIRD_PF, RTM_GETROUTE);
   while (h = nl_get_scan())
     if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
       nl_parse_route(h, 1);
@@ -1055,11 +1072,9 @@ nl_open_async(void)
 
   bzero(&sa, sizeof(sa));
   sa.nl_family = AF_NETLINK;
-#ifdef IPV6
-  sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE;
-#else
-  sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE;
-#endif
+  sa.nl_groups = RTMGRP_LINK |
+    RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
+    RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE;
   if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0)
     {
       log(L_ERR "Unable to bind asynchronous rtnetlink socket: %m");
index 90b3ebd9b4e4d74456a000d8513aa7be1d0144d0..90e164fbb3085fd5a8bcd5ef9d642f9733aae675 100644 (file)
@@ -6,9 +6,11 @@
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 
+#include <linux/socket.h>
+#include <linux/tcp.h>
+
 #include <net/if.h>
 
-#ifdef IPV6
 
 #ifndef IPV6_UNICAST_HOPS
 /* Needed on glibc 2.0 systems */
 #define CONFIG_IPV6_GLIBC_20
 #endif
 
-static inline void
-set_inaddr(struct in6_addr *ia, ip_addr a)
-{
-  ipa_hton(a);
-  memcpy(ia, &a, sizeof(a));
-}
 
-static inline void
-get_inaddr(ip_addr *a, struct in6_addr *ia)
-{
-  memcpy(a, ia, sizeof(*a));
-  ipa_ntoh(*a);
-}
 
 static inline char *
-sysio_bind_to_iface(sock *s)
+sk_bind_to_iface(sock *s)
 {
   struct ifreq ifr;
   strcpy(ifr.ifr_name, s->iface->name);
@@ -41,22 +31,6 @@ sysio_bind_to_iface(sock *s)
   return NULL;
 }
 
-#else
-
-static inline void
-set_inaddr(struct in_addr *ia, ip_addr a)
-{
-  ipa_hton(a);
-  memcpy(&ia->s_addr, &a, sizeof(a));
-}
-
-static inline void
-get_inaddr(ip_addr *a, struct in_addr *ia)
-{
-  memcpy(a, &ia->s_addr, sizeof(*a));
-  ipa_ntoh(*a);
-}
-
 
 #ifndef HAVE_STRUCT_IP_MREQN
 /* Several versions of glibc don't define this structure, so we have to do it ourselves */
@@ -73,12 +47,12 @@ static inline void fill_mreqn(struct ip_mreqn *m, struct iface *ifa, ip_addr sad
 {
   bzero(m, sizeof(*m));
   m->imr_ifindex = ifa->index;
-  set_inaddr(&m->imr_address, saddr);
-  set_inaddr(&m->imr_multiaddr, maddr);
+  ipa_put_in4(&m->imr_address, saddr);
+  ipa_put_in4(&m->imr_multiaddr, maddr);
 }
 
 static inline char *
-sysio_setup_multicast(sock *s)
+sk_setup_multicast4(sock *s)
 {
   struct ip_mreqn m;
   int zero = 0;
@@ -95,16 +69,11 @@ sysio_setup_multicast(sock *s)
     return "IP_MULTICAST_IF";
 
   /* Is this necessary? */
-  struct ifreq ifr;
-  strcpy(ifr.ifr_name, s->iface->name);
-  if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0)
-    return "SO_BINDTODEVICE";
-
-  return NULL;
+  return sk_bind_to_iface(s);
 }
 
 static inline char *
-sysio_join_group(sock *s, ip_addr maddr)
+sk_join_group4(sock *s, ip_addr maddr)
 {
   struct ip_mreqn m;
 
@@ -117,7 +86,7 @@ sysio_join_group(sock *s, ip_addr maddr)
 }
 
 static inline char *
-sysio_leave_group(sock *s, ip_addr maddr)
+sk_leave_group4(sock *s, ip_addr maddr)
 {
   struct ip_mreqn m;
 
@@ -129,11 +98,7 @@ sysio_leave_group(sock *s, ip_addr maddr)
   return NULL;
 }
 
-#endif
-
 
-#include <linux/socket.h>
-#include <linux/tcp.h>
 
 /* For the case that we have older kernel headers */
 /* Copied from Linux kernel file include/linux/tcp.h */
@@ -154,12 +119,12 @@ struct tcp_md5sig {
 #endif
 
 static int
-sk_set_md5_auth_int(sock *s, sockaddr *sa, char *passwd)
+sk_set_md5_auth_int(sock *s, struct sockaddr *sa, int sa_len, char *passwd)
 {
   struct tcp_md5sig md5;
 
   memset(&md5, 0, sizeof(md5));
-  memcpy(&md5.tcpm_addr, (struct sockaddr *) sa, sizeof(*sa));
+  memcpy(&md5.tcpm_addr, sa, sa_len);
 
   if (passwd)
     {
@@ -182,57 +147,42 @@ sk_set_md5_auth_int(sock *s, sockaddr *sa, char *passwd)
       if (errno == ENOPROTOOPT)
        log(L_ERR "Kernel does not support TCP MD5 signatures");
       else
-       log(L_ERR "sk_set_md5_auth_int: setsockopt: %m");
+       log(L_ERR "sk_set_md5_auth_int: TCP_MD5SIG: %m");
     }
 
   return rv;
 }
 
 
-#ifndef IPV6
-
 /* RX/TX packet info handling for IPv4 */
 /* Mostly similar to standardized IPv6 code */
 
-#define CMSG_RX_SPACE CMSG_SPACE(sizeof(struct in_pktinfo))
-#define CMSG_TX_SPACE CMSG_SPACE(sizeof(struct in_pktinfo))
+#define CMSG_SPACE_PKTINFO4 CMSG_SPACE(sizeof(struct in_pktinfo))
+#define CMSG_SPACE_PKTINFO6 CMSG_SPACE(sizeof(struct in6_pktinfo))
+
+#define CMSG_RX_SPACE MAX(CMSG_SPACE_PKTINFO4,CMSG_SPACE_PKTINFO6)
+#define CMSG_TX_SPACE MAX(CMSG_SPACE_PKTINFO4,CMSG_SPACE_PKTINFO6)
 
-static char *
-sysio_register_cmsgs(sock *s)
+static inline char *
+sk_request_pktinfo4(sock *s)
 {
   int ok = 1;
-  if ((s->flags & SKF_LADDR_RX) &&
-      setsockopt(s->fd, IPPROTO_IP, IP_PKTINFO, &ok, sizeof(ok)) < 0)
-    return "IP_PKTINFO";
+  if (s->flags & SKF_LADDR_RX)
+    if (setsockopt(s->fd, IPPROTO_IP, IP_PKTINFO, &ok, sizeof(ok)) < 0)
+      return "IP_PKTINFO";
 
   return NULL;
 }
 
-static void
-sysio_process_rx_cmsgs(sock *s, struct msghdr *msg)
+static inline void
+sk_process_rx_cmsg4(sock *s, struct cmsghdr *cm)
 {
-  struct cmsghdr *cm;
-  struct in_pktinfo *pi = NULL;
-
-  if (!(s->flags & SKF_LADDR_RX))
-    return;
-
-  for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm))
+  if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_PKTINFO)
     {
-      if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_PKTINFO)
-       pi = (struct in_pktinfo *) CMSG_DATA(cm);
+      struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cm);
+      s->laddr = ipa_get_in4(&pi->ipi_addr);
+      s->lifindex = pi->ipi_ifindex;
     }
-
-  if (!pi)
-    {
-      s->laddr = IPA_NONE;
-      s->lifindex = 0;
-      return;
-    }
-
-  get_inaddr(&s->laddr, &pi->ipi_addr);
-  s->lifindex = pi->ipi_ifindex;
-  return;
 }
 
 /*
@@ -261,8 +211,6 @@ sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
 }
 */
 
-#endif
-
 
 #ifndef IP_MINTTL
 #define IP_MINTTL 21
@@ -273,7 +221,8 @@ sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
 #endif
 
 
-#ifndef IPV6
+// XXXX
+#if 0
 
 static int
 sk_set_min_ttl4(sock *s, int ttl)
@@ -291,8 +240,6 @@ sk_set_min_ttl4(sock *s, int ttl)
   return 0;
 }
 
-#else
-
 static int
 sk_set_min_ttl6(sock *s, int ttl)
 {
index 475d660cdeb9ca87269fb79f2f25da975a6dc9d6..de21f68061b92d06079b226507bf505c3e059b81 100644 (file)
@@ -581,97 +581,106 @@ static struct resclass sk_class = {
   NULL
 };
 
-/**
- * sk_new - create a socket
- * @p: pool
- *
- * This function creates a new socket resource. If you want to use it,
- * you need to fill in all the required fields of the structure and
- * call sk_open() to do the actual opening of the socket.
- */
-sock *
-sk_new(pool *p)
-{
-  sock *s = ralloc(p, &sk_class);
-  s->pool = p;
-  // s->saddr = s->daddr = IPA_NONE;
-  s->tos = s->ttl = -1;
-  s->fd = -1;
-  return s;
-}
+#define SOCKADDR_DEFINE(sa, len, af) struct sockaddr *sa; int len; sockaddr_init(sa, len, af)
+#define sockaddr_init(sa, len, af) do { len=sockaddr_size(af); sa=alloca(len); sa->sa_family=af; } while(0)
 
-static void
-sk_insert(sock *s)
+static inline int sockaddr_size(int af)
+{ return (af == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); }
+
+static inline void
+sockaddr_fill4(struct sockaddr_in *sa, ip_addr a, struct iface *ifa, unsigned port)
 {
-  add_tail(&sock_list, &s->n);
-  sock_recalc_fdsets_p = 1;
+  sa->sin_port = htons(port);
+#ifdef HAVE_SIN_LEN
+  sa->sin_len = sizeof(struct sockaddr_in);
+#endif
+  ipa_put_in4(&sa->sin_addr, a);
 }
 
-#ifdef IPV6
-
-void
-fill_in_sockaddr(struct sockaddr_in6 *sa, ip_addr a, struct iface *ifa, unsigned port)
+static inline void
+sockaddr_fill6(struct sockaddr_in6 *sa, ip_addr a, struct iface *ifa, unsigned port)
 {
-  memset(sa, 0, sizeof (struct sockaddr_in6));
-  sa->sin6_family = AF_INET6;
   sa->sin6_port = htons(port);
   sa->sin6_flowinfo = 0;
-#ifdef HAVE_SIN_LEN
+#ifdef SIN6_LEN
   sa->sin6_len = sizeof(struct sockaddr_in6);
 #endif
-  set_inaddr(&sa->sin6_addr, a);
-
-  if (ifa && ipa_has_link_scope(a))
-    sa->sin6_scope_id = ifa->index;
+  ipa_put_in6(&sa->sin6_addr, a);
+  sa->sin6_scope_id = (ifa && ipa_is_link_local(a)) ? ifa->index : 0;
 }
 
 void
-get_sockaddr(struct sockaddr_in6 *sa, ip_addr *a, struct iface **ifa, unsigned *port, int check)
+sockaddr_fill(struct sockaddr *sa, ip_addr a, struct iface *ifa, unsigned port)
+{
+  if (sa->sa_family == AF_INET)
+    sockaddr_fill4((struct sockaddr_in *) sa, a, ifa, port);
+  else if (sa->sa_family == AF_INET6)
+    sockaddr_fill6((struct sockaddr_in6 *) sa, a, ifa, port);
+  else
+    bug("%s called for wrong AF (%d)", "sockaddr_fill", sa->sa_family);
+}
+
+static inline void
+sockaddr_read4(struct sockaddr_in *sa, ip_addr *a, struct iface **ifa, unsigned *port)
+{
+  if (port)
+    *port = ntohs(sa->sin_port);
+  *a = ipa_get_in4(&sa->sin_addr);
+}
+
+static inline void
+sockaddr_read6(struct sockaddr_in6 *sa, ip_addr *a, struct iface **ifa, unsigned *port)
 {
-  if (check && sa->sin6_family != AF_INET6)
-    bug("get_sockaddr called for wrong address family (%d)", sa->sin6_family);
   if (port)
     *port = ntohs(sa->sin6_port);
-  memcpy(a, &sa->sin6_addr, sizeof(*a));
-  ipa_ntoh(*a);
+  *a = ipa_get_in6(&sa->sin6_addr);
 
-  if (ifa && ipa_has_link_scope(*a))
+  if (ifa && ipa_is_link_local(*a))
     *ifa = if_find_by_index(sa->sin6_scope_id);
 }
 
-#else
-
 void
-fill_in_sockaddr(struct sockaddr_in *sa, ip_addr a, struct iface *ifa, unsigned port)
+sockaddr_read(struct sockaddr *sa, ip_addr *a, struct iface **ifa, unsigned *port, int check)
 {
-  memset (sa, 0, sizeof (struct sockaddr_in));
-  sa->sin_family = AF_INET;
-  sa->sin_port = htons(port);
-#ifdef HAVE_SIN_LEN
-  sa->sin_len = sizeof(struct sockaddr_in);
-#endif
-  set_inaddr(&sa->sin_addr, a);
+  if (sa->sa_family == AF_INET)
+    sockaddr_read4((struct sockaddr_in *) sa, a, ifa, port);
+  else if (sa->sa_family == AF_INET6)
+    sockaddr_read6((struct sockaddr_in6 *) sa, a, ifa, port);
+  else if (check)
+    bug("%s called for wrong AF (%d)", "sockaddr_read", sa->sa_family);
 }
 
-void
-get_sockaddr(struct sockaddr_in *sa, ip_addr *a, struct iface **ifa, unsigned *port, int check)
+
+
+/**
+ * sk_new - create a socket
+ * @p: pool
+ *
+ * This function creates a new socket resource. If you want to use it,
+ * you need to fill in all the required fields of the structure and
+ * call sk_open() to do the actual opening of the socket.
+ */
+sock *
+sk_new(pool *p)
 {
-  if (check && sa->sin_family != AF_INET)
-    bug("get_sockaddr called for wrong address family (%d)", sa->sin_family);
-  if (port)
-    *port = ntohs(sa->sin_port);
-  memcpy(a, &sa->sin_addr.s_addr, sizeof(*a));
-  ipa_ntoh(*a);
+  sock *s = ralloc(p, &sk_class);
+  s->pool = p;
+  // s->saddr = s->daddr = IPA_NONE;
+  s->tos = s->ttl = -1;
+  s->fd = -1;
+  return s;
 }
 
-#endif
+static void
+sk_insert(sock *s)
+{
+  add_tail(&sock_list, &s->n);
+  sock_recalc_fdsets_p = 1;
+}
 
 
-#ifdef IPV6
 
 /* PKTINFO handling is also standardized in IPv6 */
-#define CMSG_RX_SPACE CMSG_SPACE(sizeof(struct in6_pktinfo))
-#define CMSG_TX_SPACE CMSG_SPACE(sizeof(struct in6_pktinfo))
 
 /*
  * RFC 2292 uses IPV6_PKTINFO for both the socket option and the cmsg
@@ -683,42 +692,39 @@ get_sockaddr(struct sockaddr_in *sa, ip_addr *a, struct iface **ifa, unsigned *p
 #define IPV6_RECVPKTINFO IPV6_PKTINFO
 #endif
 
-static char *
-sysio_register_cmsgs(sock *s)
+static inline char *
+sk_request_pktinfo6(sock *s)
 {
   int ok = 1;
-  if ((s->flags & SKF_LADDR_RX) &&
-      setsockopt(s->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &ok, sizeof(ok)) < 0)
-    return "IPV6_RECVPKTINFO";
+  if (s->flags & SKF_LADDR_RX)
+    if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &ok, sizeof(ok)) < 0)
+      return "IPV6_RECVPKTINFO";
 
   return NULL;
 }
 
 static void
-sysio_process_rx_cmsgs(sock *s, struct msghdr *msg)
+sk_process_rx_cmsgs(sock *s, struct msghdr *msg)
 {
   struct cmsghdr *cm;
-  struct in6_pktinfo *pi = NULL;
 
   if (!(s->flags & SKF_LADDR_RX))
     return;
 
+  s->laddr = IPA_NONE;
+  s->lifindex = 0;
+
   for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm))
     {
       if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PKTINFO)
-       pi = (struct in6_pktinfo *) CMSG_DATA(cm);
-    }
+       {
+         struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cm);
+         s->laddr = ipa_get_in6(&pi->ipi6_addr);
+         s->lifindex = pi->ipi6_ifindex;
+       }
 
-  if (!pi)
-    {
-      s->laddr = IPA_NONE;
-      s->lifindex = 0;
-      return;
+      sk_process_rx_cmsg4(s, cm);
     }
-
-  get_inaddr(&s->laddr, &pi->ipi6_addr);
-  s->lifindex = pi->ipi6_ifindex;
-  return;
 }
 
 /*
@@ -747,25 +753,6 @@ sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
   return;
 }
 */
-#endif
-
-static char *
-sk_set_ttl_int(sock *s)
-{
-#ifdef IPV6
-  if (setsockopt(s->fd, SOL_IPV6, IPV6_UNICAST_HOPS, &s->ttl, sizeof(s->ttl)) < 0)
-    return "IPV6_UNICAST_HOPS";
-#else
-  if (setsockopt(s->fd, SOL_IP, IP_TTL, &s->ttl, sizeof(s->ttl)) < 0)
-    return "IP_TTL";
-#ifdef CONFIG_UNIX_DONTROUTE
-  int one = 1;
-  if (s->ttl == 1 && setsockopt(s->fd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof(one)) < 0)
-    return "SO_DONTROUTE";
-#endif 
-#endif
-  return NULL;
-}
 
 #define ERR(x) do { err = x; goto bad; } while(0)
 #define WARN(x) log(L_WARN "sk_setup: %s: %m", x)
@@ -773,28 +760,32 @@ sk_set_ttl_int(sock *s)
 static char *
 sk_setup(sock *s)
 {
+  int one = 1;
   int fd = s->fd;
   char *err = NULL;
 
   if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
     ERR("fcntl(O_NONBLOCK)");
-  if (s->type == SK_UNIX)
+
+  if (!s->af)
     return NULL;
-#ifndef IPV6
-  if ((s->tos >= 0) && setsockopt(fd, SOL_IP, IP_TOS, &s->tos, sizeof(s->tos)) < 0)
-    WARN("IP_TOS");
-#endif
 
-#ifdef IPV6
-  int v = 1;
-  if ((s->flags & SKF_V6ONLY) && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &v, sizeof(v)) < 0)
-    WARN("IPV6_V6ONLY");
-#endif
+  if (sk_is_ipv4(s) && (s->tos >= 0))
+    if (setsockopt(fd, SOL_IP, IP_TOS, &s->tos, sizeof(s->tos)) < 0)
+      WARN("IP_TOS");
+
+  if (sk_is_ipv6(s) && (s->flags & SKF_V6ONLY))
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)) < 0)
+      WARN("IPV6_V6ONLY");
 
+  // XXXX better error handling
   if (s->ttl >= 0)
-    err = sk_set_ttl_int(s);
+    sk_set_ttl(s, s->ttl);
 
-  sysio_register_cmsgs(s);
+  if (sk_is_ipv4(s))
+    err = sk_request_pktinfo4(s);
+  else
+    err = sk_request_pktinfo6(s);
 bad:
   return err;
 }
@@ -816,11 +807,30 @@ sk_set_ttl(sock *s, int ttl)
 {
   char *err;
 
+  if (sk_is_ipv4(s))
+    {
+      if (setsockopt(s->fd, SOL_IP, IP_TTL, &ttl, sizeof(ttl)) < 0)
+       ERR("IP_TTL");
+
+#ifdef CONFIG_UNIX_DONTROUTE
+      int one = 1;
+      if (ttl == 1)
+       if (setsockopt(s->fd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof(one)) < 0)
+         ERR("SO_DONTROUTE");
+#endif
+    }
+  else
+    {
+      if (setsockopt(s->fd, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0)
+       ERR("IPV6_UNICAST_HOPS");
+    }
+
   s->ttl = ttl;
-  if (err = sk_set_ttl_int(s))
-    log(L_ERR "sk_set_ttl: %s: %m", err);
+  return 0;
 
-  return (err ? -1 : 0);
+ bad:
+  log(L_ERR "sk_set_ttl: %s: %m", err);
+  return -1;
 }
 
 /**
@@ -836,16 +846,30 @@ sk_set_ttl(sock *s, int ttl)
 int
 sk_set_min_ttl(sock *s, int ttl)
 {
-  int err;
-#ifdef IPV6
-  err = sk_set_min_ttl6(s, ttl);
-#else
-  err = sk_set_min_ttl4(s, ttl);
-#endif
+  char *err;
 
-  return err;
+  if (sk_is_ipv4(s))
+    {
+      if (setsockopt(s->fd, IPPROTO_IP, IP_MINTTL, &ttl, sizeof(ttl)) < 0)
+       ERR("IP_MINTTL");
+    }
+  else
+    {
+      if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_MINHOPCOUNT, &ttl, sizeof(ttl)) < 0)
+       ERR("IPV6_MINHOPCOUNT");
+    }
+
+  return 0;
+
+ bad:
+  if (errno == ENOPROTOOPT)
+    log(L_ERR "Kernel does not support %s TTL security", sk_is_ipv4(s) ? "IPv4" : "IPv6");
+  else
+    log(L_ERR "sk_set_min_ttl: %s: %m", err);
+  return -1;
 }
 
+
 /**
  * sk_set_md5_auth - add / remove MD5 security association for given socket.
  * @s: socket
@@ -868,9 +892,9 @@ sk_set_min_ttl(sock *s, int ttl)
 int
 sk_set_md5_auth(sock *s, ip_addr a, struct iface *ifa, char *passwd)
 {
-  sockaddr sa;
-  fill_in_sockaddr(&sa, a, ifa, 0);
-  return sk_set_md5_auth_int(s, &sa, passwd);
+  SOCKADDR_DEFINE(sa, sa_len, s->af);
+  sockaddr_fill(sa, a, ifa, 0);
+  return sk_set_md5_auth_int(s, sa, sa_len, passwd);
 }
 
 int
@@ -885,9 +909,6 @@ sk_set_broadcast(sock *s, int enable)
   return 0;
 }
 
-
-#ifdef IPV6
-
 int
 sk_set_ipv6_checksum(sock *s, int offset)
 {
@@ -901,7 +922,7 @@ sk_set_ipv6_checksum(sock *s, int offset)
 }
 
 int
-sk_set_icmp_filter(sock *s, int p1, int p2)
+sk_set_icmp6_filter(sock *s, int p1, int p2)
 {
   /* a bit of lame interface, but it is here only for Radv */
   struct icmp6_filter f;
@@ -912,122 +933,120 @@ sk_set_icmp_filter(sock *s, int p1, int p2)
 
   if (setsockopt(s->fd, IPPROTO_ICMPV6, ICMP6_FILTER, &f, sizeof(f)) < 0)
     {
-      log(L_ERR "sk_setup_icmp_filter: ICMP6_FILTER: %m");
+      log(L_ERR "sk_set_icmp6_filter: ICMP6_FILTER: %m");
       return -1;
     }
 
   return 0;
 }
 
-int
-sk_setup_multicast(sock *s)
+
+static inline void
+fill_mreq6(struct ipv6_mreq *m, struct iface *ifa, ip_addr maddr)
 {
-  char *err;
-  int zero = 0;
-  int index;
+  bzero(m, sizeof(*m));
 
-  ASSERT(s->iface && s->iface->addr);
+#ifdef CONFIG_IPV6_GLIBC_20
+  m->ipv6mr_ifindex = ifa->index;
+#else
+  m->ipv6mr_interface = ifa->index;
+#endif
+
+  ipa_put_in6(&m->ipv6mr_multiaddr, maddr);
+}
+
+static inline char *
+sk_setup_multicast6(sock *s)
+{
+  int zero = 0;
+  int index = s->iface->index;
 
-  index = s->iface->index;
   if (setsockopt(s->fd, SOL_IPV6, IPV6_MULTICAST_HOPS, &s->ttl, sizeof(s->ttl)) < 0)
-    ERR("IPV6_MULTICAST_HOPS");
+    return "IPV6_MULTICAST_HOPS";
   if (setsockopt(s->fd, SOL_IPV6, IPV6_MULTICAST_LOOP, &zero, sizeof(zero)) < 0)
-    ERR("IPV6_MULTICAST_LOOP");
+    return "IPV6_MULTICAST_LOOP";
   if (setsockopt(s->fd, SOL_IPV6, IPV6_MULTICAST_IF, &index, sizeof(index)) < 0)
-    ERR("IPV6_MULTICAST_IF");
-
-  if (err = sysio_bind_to_iface(s))
-    goto bad;
-
-  return 0;
+    return "IPV6_MULTICAST_IF";
 
-bad:
-  log(L_ERR "sk_setup_multicast: %s: %m", err);
-  return -1;
+  /* Is this necessary? */
+  return sk_bind_to_iface(s);
 }
 
 int
-sk_join_group(sock *s, ip_addr maddr)
+sk_setup_multicast(sock *s)
 {
-  struct ipv6_mreq mreq;
+  char *err;
 
-  set_inaddr(&mreq.ipv6mr_multiaddr, maddr);
+  ASSERT(s->iface && s->iface->addr);
 
-#ifdef CONFIG_IPV6_GLIBC_20
-  mreq.ipv6mr_ifindex = s->iface->index;
-#else
-  mreq.ipv6mr_interface = s->iface->index;
-#endif
+  if (sk_is_ipv4(s))
+    err = sk_setup_multicast4(s);
+  else
+    err = sk_setup_multicast6(s);
 
-  if (setsockopt(s->fd, SOL_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) < 0)
+  if (err)
     {
-      log(L_ERR "sk_join_group: IPV6_JOIN_GROUP: %m");
+      log(L_ERR "sk_setup_multicast: %s: %m", err);
       return -1;
     }
 
   return 0;
 }
 
-int
-sk_leave_group(sock *s, ip_addr maddr)
+static inline char *
+sk_join_group6(sock *s, ip_addr maddr)
 {
-  struct ipv6_mreq mreq;
-       
-  set_inaddr(&mreq.ipv6mr_multiaddr, maddr);
+  struct ipv6_mreq m;
 
-#ifdef CONFIG_IPV6_GLIBC_20
-  mreq.ipv6mr_ifindex = s->iface->index;
-#else
-  mreq.ipv6mr_interface = s->iface->index;
-#endif
-
-  if (setsockopt(s->fd, SOL_IPV6, IPV6_LEAVE_GROUP, &mreq, sizeof(mreq)) < 0)
-    {
-      log(L_ERR "sk_leave_group: IPV6_LEAVE_GROUP: %m");
-      return -1;
-    }
+  fill_mreq6(&m, s->iface, maddr);
+  if (setsockopt(s->fd, SOL_IPV6, IPV6_JOIN_GROUP, &m, sizeof(m)) < 0)
+    return "IPV6_JOIN_GROUP";
 
-  return 0;
+  return NULL;
 }
 
-#else /* IPV4 */
-
 int
-sk_setup_multicast(sock *s)
+sk_join_group(sock *s, ip_addr maddr)
 {
   char *err;
 
-  ASSERT(s->iface && s->iface->addr);
+  if (sk_is_ipv4(s))
+    err = sk_join_group4(s, maddr);
+  else
+    err = sk_join_group6(s, maddr);
 
-  if (err = sysio_setup_multicast(s))
+  if (err)
     {
-      log(L_ERR "sk_setup_multicast: %s: %m", err);
+      log(L_ERR "sk_join_group: %s: %m", err);
       return -1;
     }
 
   return 0;
 }
 
-int
-sk_join_group(sock *s, ip_addr maddr)
+static inline char *
+sk_leave_group6(sock *s, ip_addr maddr)
 {
char *err;
 struct ipv6_mreq m;
 
- if (err = sysio_join_group(s, maddr))
-    {
-      log(L_ERR "sk_join_group: %s: %m", err);
-      return -1;
-    }
+  fill_mreq6(&m, s->iface, maddr);
+  if (setsockopt(s->fd, SOL_IPV6, IPV6_LEAVE_GROUP, &m, sizeof(m)) < 0)
+    return "IPV6_LEAVE_GROUP";
 
-  return 0;
+  return NULL;
 }
 
 int
 sk_leave_group(sock *s, ip_addr maddr)
 {
- char *err;
+  char *err;
+
+  if (sk_is_ipv4(s))
+    err = sk_leave_group4(s, maddr);
+  else
+    err = sk_leave_group6(s, maddr);
 
if (err = sysio_leave_group(s, maddr))
 if (err)
     {
       log(L_ERR "sk_leave_group: %s: %m", err);
       return -1;
@@ -1036,16 +1055,15 @@ sk_leave_group(sock *s, ip_addr maddr)
   return 0;
 }
 
-#endif 
 
 
 static void
 sk_tcp_connected(sock *s)
 {
-  sockaddr lsa;
-  int lsa_len = sizeof(lsa);
-  if (getsockname(s->fd, (struct sockaddr *) &lsa, &lsa_len) == 0)
-    get_sockaddr(&lsa, &s->saddr, &s->iface, &s->sport, 1);
+  SOCKADDR_DEFINE(sa, sa_len, s->af);
+
+  if (getsockname(s->fd, sa, &sa_len) == 0)
+    sockaddr_read(sa, &s->saddr, &s->iface, &s->sport, 1);
 
   s->type = SK_TCP;
   sk_alloc_bufs(s);
@@ -1053,35 +1071,35 @@ sk_tcp_connected(sock *s)
 }
 
 static int
-sk_passive_connected(sock *s, struct sockaddr *sa, int al, int type)
+sk_passive_connected(sock *s, struct sockaddr *sa, int sa_len, int type)
 {
-  int fd = accept(s->fd, sa, &al);
+  int fd = accept(s->fd, sa, &sa_len);
   if (fd >= 0)
     {
       sock *t = sk_new(s->pool);
       char *err;
       t->type = type;
       t->fd = fd;
+      t->af = s->af;
       t->ttl = s->ttl;
       t->tos = s->tos;
       t->rbsize = s->rbsize;
       t->tbsize = s->tbsize;
       if (type == SK_TCP)
        {
-         sockaddr lsa;
-         int lsa_len = sizeof(lsa);
-         if (getsockname(fd, (struct sockaddr *) &lsa, &lsa_len) == 0)
-           get_sockaddr(&lsa, &t->saddr, &t->iface, &t->sport, 1);
+         SOCKADDR_DEFINE(lsa, lsa_len, t->af);
+         if (getsockname(fd, lsa, &lsa_len) == 0) // XXXX
+           sockaddr_read(lsa, &t->saddr, &t->iface, &t->sport, 1);
 
-         get_sockaddr((sockaddr *) sa, &t->daddr, &t->iface, &t->dport, 1);
+         sockaddr_read(sa, &t->daddr, &t->iface, &t->dport, 1);
        }
-      sk_insert(t);
       if (err = sk_setup(t))
        {
-         log(L_ERR "Incoming connection: %s: %m", err);
+         log(L_ERR "sk_passive_connected: %s: %m", err);
          rfree(t);
          return 1;
        }
+      sk_insert(t);
       sk_alloc_bufs(t);
       s->rx_hook(t, 0);
       return 1;
@@ -1106,9 +1124,6 @@ sk_passive_connected(sock *s, struct sockaddr *sa, int al, int type)
 int
 sk_open(sock *s)
 {
-  int fd;
-  sockaddr sa;
-  int one = 1;
   int type = s->type;
   int has_src = ipa_nonzero(s->saddr) || s->sport;
   char *err;
@@ -1119,27 +1134,35 @@ sk_open(sock *s)
       s->ttx = "";                     /* Force s->ttx != s->tpos */
       /* Fall thru */
     case SK_TCP_PASSIVE:
-      fd = socket(BIRD_PF, SOCK_STREAM, IPPROTO_TCP);
+      s->af = (s->flags & SKF_V4ONLY) ? AF_INET : AF_INET6;
+      s->fd = socket(s->af, SOCK_STREAM, IPPROTO_TCP);
       break;
     case SK_UDP:
-      fd = socket(BIRD_PF, SOCK_DGRAM, IPPROTO_UDP);
+      s->af = (s->flags & SKF_V4ONLY) ? AF_INET : AF_INET6;
+      s->fd = socket(s->af, SOCK_DGRAM, IPPROTO_UDP);
       break;
     case SK_IP:
-      fd = socket(BIRD_PF, SOCK_RAW, s->dport);
+      s->af = (s->flags & SKF_V4ONLY) ? AF_INET : AF_INET6;
+      s->fd = socket(s->af, SOCK_RAW, s->dport);
       break;
     case SK_MAGIC:
-      fd = s->fd;
-      break;
+      if (err = sk_setup(s))
+       goto bad;
+      sk_insert(s);
+      return 0;
     default:
       bug("sk_open() called for invalid sock type %d", type);
     }
+
+  int fd = s->fd;
   if (fd < 0)
-    die("sk_open: socket: %m");
-  s->fd = fd;
+    ERR("socket");
 
   if (err = sk_setup(s))
     goto bad;
 
+  SOCKADDR_DEFINE(sa, sa_len, s->af);
+
   if (has_src)
     {
       int port;
@@ -1149,26 +1172,26 @@ sk_open(sock *s)
       else
        {
          port = s->sport;
+
+         int one = 1;
          if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
            ERR("SO_REUSEADDR");
        }
-      fill_in_sockaddr(&sa, s->saddr, s->iface, port);
-      if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0)
+
+      sockaddr_fill(sa, s->saddr, s->iface, port);
+      if (bind(fd, sa, sa_len) < 0)
        ERR("bind");
     }
-  fill_in_sockaddr(&sa, s->daddr, s->iface, s->dport);
+  sockaddr_fill(sa, s->daddr, s->iface, s->dport);
 
   if (s->password)
-    {
-      int rv = sk_set_md5_auth_int(s, &sa, s->password);
-      if (rv < 0)
-       goto bad_no_log;
-    }
+    if (sk_set_md5_auth_int(s, sa, sa_len, s->password) < 0)
+      goto bad_no_log;
 
   switch (type)
     {
     case SK_TCP_ACTIVE:
-      if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) >= 0)
+      if (connect(fd, sa, sa_len) >= 0)
        sk_tcp_connected(s);
       else if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS &&
               errno != ECONNREFUSED && errno != EHOSTUNREACH && errno != ENETUNREACH)
@@ -1178,26 +1201,25 @@ sk_open(sock *s)
       if (listen(fd, 8))
        ERR("listen");
       break;
-    case SK_MAGIC:
-      break;
     default:
       sk_alloc_bufs(s);
-#ifdef IPV6
-#ifdef IPV6_MTU_DISCOVER
-      {
-       int dont = IPV6_PMTUDISC_DONT;
-       if (setsockopt(fd, SOL_IPV6, IPV6_MTU_DISCOVER, &dont, sizeof(dont)) < 0)
-         ERR("IPV6_MTU_DISCOVER");
-      }
-#endif
-#else
+
 #ifdef IP_PMTUDISC
-      {
-       int dont = IP_PMTUDISC_DONT;
-       if (setsockopt(fd, SOL_IP, IP_PMTUDISC, &dont, sizeof(dont)) < 0)
-         ERR("IP_PMTUDISC");
-      }
+      if (sk_is_ipv4(s))
+       {
+         int dont = IP_PMTUDISC_DONT;
+         if (setsockopt(fd, SOL_IP, IP_PMTUDISC, &dont, sizeof(dont)) < 0)
+           ERR("IP_PMTUDISC");
+       }
 #endif
+
+#ifdef IPV6_MTU_DISCOVER
+      if (sk_is_ipv6(s))
+       {
+         int dont = IPV6_PMTUDISC_DONT;
+         if (setsockopt(fd, SOL_IPV6, IPV6_MTU_DISCOVER, &dont, sizeof(dont)) < 0)
+           ERR("IPV6_MTU_DISCOVER");
+       }
 #endif
     }
 
@@ -1207,7 +1229,8 @@ sk_open(sock *s)
 bad:
   log(L_ERR "sk_open: %s: %m", err);
 bad_no_log:
-  close(fd);
+  close(s->fd);
+  s->af = 0;
   s->fd = -1;
   return -1;
 }
@@ -1278,15 +1301,15 @@ sk_maybe_write(sock *s)
        if (s->tbuf == s->tpos)
          return 1;
 
-       sockaddr sa;
-       fill_in_sockaddr(&sa, s->daddr, s->iface, s->dport);
+       SOCKADDR_DEFINE(sa, sa_len, s->af);
+       sockaddr_fill(sa, s->daddr, s->iface, s->dport);
 
        struct iovec iov = {s->tbuf, s->tpos - s->tbuf};
        // byte cmsg_buf[CMSG_TX_SPACE];
 
        struct msghdr msg = {
-         .msg_name = &sa,
-         .msg_namelen = sizeof(sa),
+         .msg_name = sa,
+         .msg_namelen = sa_len,
          .msg_iov = &iov,
          .msg_iovlen = 1};
 
@@ -1396,13 +1419,12 @@ sk_read(sock *s)
     {
     case SK_TCP_PASSIVE:
       {
-       sockaddr sa;
-       return sk_passive_connected(s, (struct sockaddr *) &sa, sizeof(sa), SK_TCP);
+       SOCKADDR_DEFINE(sa, sa_len, s->af);
+       return sk_passive_connected(s, sa, sa_len, SK_TCP);
       }
     case SK_UNIX_PASSIVE:
       {
-       struct sockaddr_un sa;
-       return sk_passive_connected(s, (struct sockaddr *) &sa, sizeof(sa), SK_UNIX);
+       return sk_passive_connected(s, NULL, 0, SK_UNIX);
       }
     case SK_TCP:
     case SK_UNIX:
@@ -1433,15 +1455,15 @@ sk_read(sock *s)
       return s->rx_hook(s, 0);
     default:
       {
-       sockaddr sa;
+       SOCKADDR_DEFINE(sa, sa_len, s->af);
        int e;
 
        struct iovec iov = {s->rbuf, s->rbsize};
        byte cmsg_buf[CMSG_RX_SPACE];
 
        struct msghdr msg = {
-         .msg_name = &sa,
-         .msg_namelen = sizeof(sa),
+         .msg_name = sa,
+         .msg_namelen = sa_len,
          .msg_iov = &iov,
          .msg_iovlen = 1,
          .msg_control = cmsg_buf,
@@ -1457,8 +1479,8 @@ sk_read(sock *s)
            return 0;
          }
        s->rpos = s->rbuf + e;
-       get_sockaddr(&sa, &s->faddr, NULL, &s->fport, 1);
-       sysio_process_rx_cmsgs(s, &msg);
+       sockaddr_read(sa, &s->faddr, NULL, &s->fport, 1);
+       sk_process_rx_cmsgs(s, &msg);
 
        s->rx_hook(s, e);
        return 1;
@@ -1473,9 +1495,10 @@ sk_write(sock *s)
     {
     case SK_TCP_ACTIVE:
       {
-       sockaddr sa;
-       fill_in_sockaddr(&sa, s->daddr, s->iface, s->dport);
-       if (connect(s->fd, (struct sockaddr *) &sa, sizeof(sa)) >= 0 || errno == EISCONN)
+       SOCKADDR_DEFINE(sa, sa_len, s->af);
+       sockaddr_fill(sa, s->daddr, s->iface, s->dport);
+
+       if (connect(s->fd, sa, sa_len) >= 0 || errno == EISCONN)
          sk_tcp_connected(s);
        else if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS)
          s->err_hook(s, errno);
index 3e85c85c9b7f9929636d9c93ed4edec363675256..a9edbebccdbff917a65e0c7635aaec2a95451051 100644 (file)
@@ -28,17 +28,11 @@ volatile int async_config_flag;
 volatile int async_dump_flag;
 volatile int async_shutdown_flag;
 
-#ifdef IPV6
+// XXXX
 #define BIRD_PF PF_INET6
 #define BIRD_AF AF_INET6
-typedef struct sockaddr_in6 sockaddr;
-static inline int sa_family_check(sockaddr *sa) { return sa->sin6_family == AF_INET6; }
-#else
-#define BIRD_PF PF_INET
-#define BIRD_AF AF_INET
-typedef struct sockaddr_in sockaddr;
-static inline int sa_family_check(sockaddr *sa) { return sa->sin_family == AF_INET; }
-#endif
+static inline int sa_family_check(struct sockaddr *sa) { return sa->sa_family == AF_INET6; }
+
 
 #ifndef SUN_LEN
 #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen ((ptr)->sun_path))
@@ -49,8 +43,6 @@ struct iface;
 
 void io_init(void);
 void io_loop(void);
-void fill_in_sockaddr(sockaddr *sa, ip_addr a, struct iface *ifa, unsigned port);
-void get_sockaddr(sockaddr *sa, ip_addr *a, struct iface **ifa, unsigned *port, int check);
 void sk_open_unix(struct birdsock *s, char *name);
 void *tracked_fopen(struct pool *, char *name, char *mode);
 void test_old_bird(char *path);
index 728e5797f2004166e655264199961cab8336fc9d..182e97c969d95b22f52e2ff8738884620ea4ac2f 100644 (file)
@@ -57,14 +57,14 @@ tags:
 
 install: all
        $(INSTALL) -d $(DESTDIR)/$(sbindir) $(DESTDIR)/$(sysconfdir) $(DESTDIR)/@runtimedir@
-       $(INSTALL_PROGRAM) -s $(exedir)/bird $(DESTDIR)/$(sbindir)/bird@SUFFIX@
+       $(INSTALL_PROGRAM) -s $(exedir)/bird $(DESTDIR)/$(sbindir)/bird
        if test -n "@CLIENT@" ; then                                                            \
-               $(INSTALL_PROGRAM) -s $(exedir)/birdc $(DESTDIR)/$(sbindir)/birdc@SUFFIX@ ;     \
+               $(INSTALL_PROGRAM) -s $(exedir)/birdc $(DESTDIR)/$(sbindir)/birdc ;             \
        fi
        if ! test -f $(DESTDIR)/@CONFIG_FILE@ ; then                                            \
                $(INSTALL_DATA) $(srcdir)/doc/bird.conf.example $(DESTDIR)/@CONFIG_FILE@ ;      \
        else                                                                                    \
-               echo "Not overwriting old bird@SUFFIX@.conf" ;                                  \
+               echo "Not overwriting old bird.conf" ;                                          \
        fi
 
 install-docs: