Diff for /embedaddon/mpd/src/iface.c between versions 1.1.1.1 and 1.1.1.3

version 1.1.1.1, 2012/02/21 23:32:47 version 1.1.1.3, 2016/11/01 09:56:12
Line 19 Line 19
 #include "netgraph.h"  #include "netgraph.h"
 #include "util.h"  #include "util.h"
   
   #include <sys/types.h>
 #include <sys/sockio.h>  #include <sys/sockio.h>
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
   #include <sys/param.h>
 #include <net/if.h>  #include <net/if.h>
 #include <net/if_types.h>  #include <net/if_types.h>
 #include <net/if_dl.h>  #include <net/if_dl.h>
Line 59 Line 61
 #include <pcap.h>  #include <pcap.h>
 #endif  #endif
   
   #include <string.h>
   
 /*  /*
  * DEFINITIONS   * DEFINITIONS
  */   */
Line 94 Line 98
   static void   IfaceNgIpv6Shutdown(Bund b);    static void   IfaceNgIpv6Shutdown(Bund b);
   
 #ifdef USE_NG_NETFLOW  #ifdef USE_NG_NETFLOW
  static int    IfaceInitNetflow(Bund b, char *path, char *hook, char in, char out);  static int    IfaceInitNetflow(Bund b, char *path, char *hook, char in, char out, int v6);
  static int    IfaceSetupNetflow(Bund b, char in, char out);  static int    IfaceSetupNetflow(Bund b, char in, char out, int v6);
  static void   IfaceShutdownNetflow(Bund b, char in, char out);  static void   IfaceShutdownNetflow(Bund b, char in, char out, int v6);
 #endif  #endif
   
 #ifdef USE_NG_IPACCT  #ifdef USE_NG_IPACCT
Line 136 Line 140
 #ifdef USE_IPFW  #ifdef USE_IPFW
   static int    IfaceAllocACL (struct acl_pool ***ap, int start, char * ifname, int number);    static int    IfaceAllocACL (struct acl_pool ***ap, int start, char * ifname, int number);
   static int    IfaceFindACL (struct acl_pool *ap, char * ifname, int number);    static int    IfaceFindACL (struct acl_pool *ap, char * ifname, int number);
  static char * IFaceParseACL (char * src, char * ifname);  static char * IfaceParseACL (char * src, IfaceState iface);
 #endif  #endif
   
   static int    IfaceSetName(Bund b, const char * ifname);    static int    IfaceSetName(Bund b, const char * ifname);
 #ifdef SIOCSIFDESCR  #ifdef SIOCSIFDESCR
   static int    IfaceSetDescr(Bund b, const char * ifdescr);    static int    IfaceSetDescr(Bund b, const char * ifdescr);
     static void   IfaceFreeDescr(IfaceState iface);
 #endif  #endif
 #ifdef SIOCAIFGROUP  #ifdef SIOCAIFGROUP
   static int    IfaceAddGroup(Bund b, const char * ifgroup);    static int    IfaceAddGroup(Bund b, const char * ifgroup);
Line 192 Line 197
   static const struct confinfo  gConfList[] = {    static const struct confinfo  gConfList[] = {
     { 0,        IFACE_CONF_ONDEMAND,            "on-demand"     },      { 0,        IFACE_CONF_ONDEMAND,            "on-demand"     },
     { 0,        IFACE_CONF_PROXY,               "proxy-arp"     },      { 0,        IFACE_CONF_PROXY,               "proxy-arp"     },
       { 0,        IFACE_CONF_KEEP_TIMEOUT,        "keep-timeout"  },
 #ifdef USE_NG_TCPMSS  #ifdef USE_NG_TCPMSS
     { 0,        IFACE_CONF_TCPMSSFIX,           "tcpmssfix"     },      { 0,        IFACE_CONF_TCPMSSFIX,           "tcpmssfix"     },
 #endif  #endif
Line 225 Line 231
   
 #ifdef USE_NG_BPF  #ifdef USE_NG_BPF
   /* A BPF filter that matches TCP SYN packets */    /* A BPF filter that matches TCP SYN packets */
  static const struct bpf_insn gTCPSYNProg[] = {  static const struct bpf_insn gTCPSYNProg[] __attribute__((used)) = {
 /*00*/  BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9),              /* A <- IP protocol */  /*00*/  BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9),              /* A <- IP protocol */
 /*01*/  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 6), /* !TCP => 8 */  /*01*/  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 6), /* !TCP => 8 */
 /*02*/  BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 6),      /* A <- fragmentation offset */  /*02*/  BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 6),      /* A <- fragmentation offset */
Line 258 Line 264
                             0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}}                              0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}}
 static const struct in6_addr in6mask128 = IN6MASK128;  static const struct in6_addr in6mask128 = IN6MASK128;
   
   #ifdef SIOCSIFDESCR
   void
   IfaceFreeDescr(IfaceState iface)
   {
     if (iface->ifdescr != NULL)
           Freee(iface->ifdescr);
     if (iface->conf.ifdescr != NULL)
           Freee(iface->conf.ifdescr);
     iface->ifdescr = iface->conf.ifdescr = NULL;
   }
   #endif
   
 /*  /*
  * IfaceInit()   * IfaceInit()
Line 277  IfaceInit(Bund b) Line 294  IfaceInit(Bund b)
 #endif  #endif
   Disable(&iface->options, IFACE_CONF_ONDEMAND);    Disable(&iface->options, IFACE_CONF_ONDEMAND);
   Disable(&iface->options, IFACE_CONF_PROXY);    Disable(&iface->options, IFACE_CONF_PROXY);
     Disable(&iface->options, IFACE_CONF_KEEP_TIMEOUT);
   Disable(&iface->options, IFACE_CONF_TCPMSSFIX);    Disable(&iface->options, IFACE_CONF_TCPMSSFIX);
 #ifdef  USE_NG_NAT  #ifdef  USE_NG_NAT
   NatInit(b);    NatInit(b);
Line 298  IfaceInst(Bund b, Bund bt) Line 316  IfaceInst(Bund b, Bund bt)
   
     memcpy(iface, &bt->iface, sizeof(*iface));      memcpy(iface, &bt->iface, sizeof(*iface));
   
   #ifdef SIOCSIFDESCR
       /* Copy interface description from template config to current */
       if (bt->iface.conf.ifdescr)
           iface->conf.ifdescr = Mstrdup(MB_IFACE, bt->iface.conf.ifdescr);
       if (bt->iface.ifdescr)
           iface->ifdescr = Mstrdup(MB_IFACE, bt->iface.ifdescr);
   #endif
     /* Copy interface name from template config to current */      /* Copy interface name from template config to current */
     if (bt->iface.conf.ifname[0] != 0 && b->tmpl == 0) {      if (bt->iface.conf.ifname[0] != 0 && b->tmpl == 0) {
         snprintf(iface->conf.ifname, sizeof(iface->conf.ifname), "%s%d",          snprintf(iface->conf.ifname, sizeof(iface->conf.ifname), "%s%d",
Line 316  IfaceDestroy(Bund b) Line 341  IfaceDestroy(Bund b)
 #ifdef SIOCSIFDESCR  #ifdef SIOCSIFDESCR
     IfaceState  const iface = &b->iface;      IfaceState  const iface = &b->iface;
   
    if (iface->conf.ifdescr != NULL)    IfaceFreeDescr(iface);
        Freee(iface->conf.ifdescr); 
 #endif  #endif
 }  }
   
Line 431  IfaceUp(Bund b, int ready) Line 455  IfaceUp(Bund b, int ready)
   
     /* Start Session timer */      /* Start Session timer */
     if (b->params.session_timeout > 0) {      if (b->params.session_timeout > 0) {
        session_timeout = b->params.session_timeout;        if (Enabled(&iface->options, IFACE_CONF_KEEP_TIMEOUT)) {
             session_timeout = b->params.session_timeout - \
                 (iface->last_up - b->last_up);
             Log(LG_IFACE2, ("[%s] IFACE: keep session-timeout at: %d seconds",
                 b->name, session_timeout));
         } else {
             session_timeout = b->params.session_timeout;
         }
     } else if (iface->session_timeout > 0) {      } else if (iface->session_timeout > 0) {
         session_timeout = iface->session_timeout;          session_timeout = iface->session_timeout;
     }      }
Line 442  IfaceUp(Bund b, int ready) Line 473  IfaceUp(Bund b, int ready)
         if (session_timeout > INT_MAX / 1100) {          if (session_timeout > INT_MAX / 1100) {
             session_timeout = INT_MAX / 1100;              session_timeout = INT_MAX / 1100;
             Log(LG_ERR, ("[%s] IFACE: session-timeout limited to %d seconds",               Log(LG_ERR, ("[%s] IFACE: session-timeout limited to %d seconds", 
                b->name, session_timeout));                b->name, session_timeout));
         }          }
         TimerInit(&iface->sessionTimer, "IfaceSession",          TimerInit(&iface->sessionTimer, "IfaceSession",
             session_timeout * SECONDS, IfaceSessionTimeout, b);              session_timeout * SECONDS, IfaceSessionTimeout, b);
Line 488  IfaceUp(Bund b, int ready) Line 519  IfaceUp(Bund b, int ready)
     if (b->params.ifdescr != NULL) {      if (b->params.ifdescr != NULL) {
        if (IfaceSetDescr(b, b->params.ifdescr) != -1) {         if (IfaceSetDescr(b, b->params.ifdescr) != -1) {
             Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Add description \"%s\"",              Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Add description \"%s\"",
                b->name, b->params.ifdescr));                b->name, iface->ifdescr));
            iface->ifdescr = b->params.ifdescr; 
         }          }
       } else if (iface->conf.ifdescr != NULL) {
          if (IfaceSetDescr(b, iface->conf.ifdescr) != -1) {
               Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Add description \"%s\"",
                   b->name, iface->ifdescr));
           }
     }      }
 #endif  #endif
 #ifdef SIOCAIFGROUP  #ifdef SIOCAIFGROUP
Line 558  IfaceUp(Bund b, int ready) Line 593  IfaceUp(Bund b, int ready)
   }    }
   acls = b->params.acl_queue;    acls = b->params.acl_queue;
   while (acls != NULL) {    while (acls != NULL) {
    buf = IFaceParseACL(acls->rule,iface->ifname);    buf = IfaceParseACL(acls->rule, iface);
     ExecCmd(LG_IFACE2, b->name, "%s queue %d config %s", PATH_IPFW, acls->real_number, buf);      ExecCmd(LG_IFACE2, b->name, "%s queue %d config %s", PATH_IPFW, acls->real_number, buf);
     Freee(buf);      Freee(buf);
     acls = acls->next;      acls = acls->next;
   }    }
   acls = b->params.acl_table;    acls = b->params.acl_table;
   while (acls != NULL) {    while (acls != NULL) {
    acl = Mdup(MB_IFACE, acls, sizeof(struct acl) + strlen(acls->rule));    /* allow both %aX and `peer_addr` macros */
     buf = IfaceParseACL(acls->rule, iface);
     strcpy(acls->rule, buf);
     Freee(buf);
     acl = Mdup(MB_IPFW, acls, sizeof(struct acl) + strlen(acls->rule));
     acl->next = iface->tables;      acl->next = iface->tables;
     iface->tables = acl;      iface->tables = acl;
    ExecCmd(LG_IFACE2, b->name, "%s table %d add %s", PATH_IPFW, acls->real_number, acls->rule);    if (strncmp(acls->rule, "peer_addr", 9) == 0) {
         char hisaddr[20];
         ExecCmd(LG_IFACE2, b->name, "%s table %d add %s",
             PATH_IPFW, acls->real_number,
             u_addrtoa(&iface->peer_addr, hisaddr, sizeof(hisaddr)));
     } else {
         ExecCmd(LG_IFACE2, b->name, "%s table %d add %s", PATH_IPFW, acls->real_number, acls->rule);
     }
     acls = acls->next;      acls = acls->next;
   };    };
   acls = b->params.acl_rule;    acls = b->params.acl_rule;
   while (acls != NULL) {    while (acls != NULL) {
    buf = IFaceParseACL(acls->rule, iface->ifname);    buf = IfaceParseACL(acls->rule, iface);
     ExecCmd(LG_IFACE2, b->name, "%s add %d %s via %s", PATH_IPFW, acls->real_number, buf, iface->ifname);      ExecCmd(LG_IFACE2, b->name, "%s add %d %s via %s", PATH_IPFW, acls->real_number, buf, iface->ifname);
     Freee(buf);      Freee(buf);
     acls = acls->next;      acls = acls->next;
Line 645  IfaceDown(Bund b) Line 691  IfaceDown(Bund b)
   };    };
   acl = iface->tables;    acl = iface->tables;
   while (acl != NULL) {    while (acl != NULL) {
    ExecCmd(LG_IFACE2, b->name, "%s table %d delete %s",    if (strncmp(acl->rule, "peer_addr", 9) == 0) {
        PATH_IPFW, acl->real_number, acl->rule);      char hisaddr[20];
       ExecCmd(LG_IFACE2, b->name, "%s table %d delete %s",
         PATH_IPFW, acl->real_number,
         u_addrtoa(&iface->peer_addr, hisaddr, sizeof(hisaddr)));
     } else {
       ExecCmd(LG_IFACE2, b->name, "%s table %d delete %s",
         PATH_IPFW, acl->real_number, acl->rule);
     }
     aclnext = acl->next;      aclnext = acl->next;
     Freee(acl);      Freee(acl);
     acl = aclnext;      acl = aclnext;
Line 688  IfaceDown(Bund b) Line 741  IfaceDown(Bund b)
       PATH_IPFW, cb);        PATH_IPFW, cb);
 #endif /* USE_IPFW */  #endif /* USE_IPFW */
   
       /* Clearing self and peer addresses */
       u_rangeclear(&iface->self_addr);
       u_addrclear(&iface->peer_addr);
       u_addrclear(&iface->self_ipv6_addr);
       u_addrclear(&iface->peer_ipv6_addr);
   
     /* Revert interface name and description */      /* Revert interface name and description */
   
     if (strcmp(iface->ngname, iface->ifname) != 0) {      if (strcmp(iface->ngname, iface->ifname) != 0) {
Line 704  IfaceDown(Bund b) Line 763  IfaceDown(Bund b)
         }          }
     }      }
 #ifdef SIOCSIFDESCR  #ifdef SIOCSIFDESCR
    if (iface->ifdescr != NULL) {    if ((iface->ifdescr != NULL)
     && (IfaceSetDescr(b, iface->conf.ifdescr) != -1)) {
         if (iface->conf.ifdescr != NULL) {          if (iface->conf.ifdescr != NULL) {
             /* Restore to config defined */  
             if (IfaceSetDescr(b, iface->conf.ifdescr) != -1) {  
                 Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Set description \"%s\"",                  Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Set description \"%s\"",
                    b->name, iface->conf.ifdescr));                    b->name, iface->ifdescr));
                iface->ifdescr = iface->conf.ifdescr; 
            } else 
                iface->ifdescr = NULL; 
         } else {          } else {
             /* Restore to original (empty) */  
             if (IfaceSetDescr(b, "") != -1) {  
                 Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Clear description",                  Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Clear description",
                     b->name));                      b->name));
             }  
             iface->ifdescr = NULL;  
         }          }
     }      }
 #endif  #endif
Line 770  IfaceAllocACL(struct acl_pool ***ap, int start, char * Line 821  IfaceAllocACL(struct acl_pool ***ap, int start, char *
     int i;      int i;
     struct acl_pool **rp,*rp1;      struct acl_pool **rp,*rp1;
   
    rp1 = Malloc(MB_IFACE, sizeof(struct acl_pool));    rp1 = Malloc(MB_IPFW, sizeof(struct acl_pool));
     strlcpy(rp1->ifname, ifname, sizeof(rp1->ifname));      strlcpy(rp1->ifname, ifname, sizeof(rp1->ifname));
     rp1->acl_number = number;      rp1->acl_number = number;
   
Line 816  IfaceFindACL (struct acl_pool *ap, char * ifname, int  Line 867  IfaceFindACL (struct acl_pool *ap, char * ifname, int 
 }  }
   
 /*  /*
 * IFaceParseACL () * IfaceParseACL ()
  *   *
 * Parces ACL and replaces %r, %p and %q macroses  * Parses ACL and replaces %r, %p and %q macroses 
  * by the real numbers of rules, queues and pipes.   * by the real numbers of rules, queues and pipes.
    *
    * Also replaces %a1 and a2 with the remote(peer)
    * or local(self) IP address respectively.
  */   */
   
 static char *  static char *
IFaceParseACL (char * src, char * ifname)IfaceParseACL (char * src, IfaceState iface)
 {  {
     char *buf,*buf1;      char *buf,*buf1;
     char *begin,*param,*end;      char *begin,*param,*end;
     char t;      char t;
     int num,real_number;      int num,real_number;
     struct acl_pool *ap;      struct acl_pool *ap;
       char hisaddr[20];
       int ipmode = 0; /* 0 - normal macro, 1 - IP address macro */
           
    buf = Malloc(MB_IFACE, ACL_LEN);    buf = Malloc(MB_IPFW, ACL_LEN);
    buf1 = Malloc(MB_IFACE, ACL_LEN);    buf1 = Malloc(MB_IPFW, ACL_LEN);
   
     strlcpy(buf, src, ACL_LEN);      strlcpy(buf, src, ACL_LEN);
     do {      do {
Line 854  IFaceParseACL (char * src, char * ifname) Line 910  IFaceParseACL (char * src, char * ifname)
                     case 't':                      case 't':
                         ap = table_pool;                          ap = table_pool;
                         break;                          break;
                       case 'a':
                           ipmode = 1;
                           if (num == 1)
                              u_addrtoa(&iface->peer_addr, hisaddr, sizeof(hisaddr));
                           else if (num == 2)
                              u_rangetoa(&iface->self_addr, hisaddr, sizeof(hisaddr));
                           else
                              ipmode = 0;
                           ap = NULL;
                           break;
                     default:                      default:
                         ap = NULL;                          ap = NULL;
                 };                  };
                real_number = IfaceFindACL(ap,ifname,num);                if (ipmode)
                if (end != NULL) {                {
                    snprintf(buf1, ACL_LEN, "%s%d %s", begin, real_number, end);                    if (end != NULL)
                } else {                        snprintf(buf1, ACL_LEN, "%s%s %s", begin, hisaddr, end);
                    snprintf(buf1, ACL_LEN, "%s%d", begin, real_number);                    else
                };                        snprintf(buf1, ACL_LEN, "%s%s", begin, hisaddr);
                     ipmode = 0;
                 }
                 else
                 {
                     real_number = IfaceFindACL(ap, iface->ifname, num);
                     if (end != NULL)
                         snprintf(buf1, ACL_LEN, "%s%d %s", begin, real_number, end);
                     else
                         snprintf(buf1, ACL_LEN, "%s%d", begin, real_number);
                 }
                 strlcpy(buf, buf1, ACL_LEN);                  strlcpy(buf, buf1, ACL_LEN);
             };              };
         };          };
Line 916  IfaceIpIfaceUp(Bund b, int ready) Line 992  IfaceIpIfaceUp(Bund b, int ready)
     /* Proxy ARP for peer if desired and peer's address is known */      /* Proxy ARP for peer if desired and peer's address is known */
     u_addrclear(&iface->proxy_addr);      u_addrclear(&iface->proxy_addr);
     if (Enabled(&iface->options, IFACE_CONF_PROXY)) {      if (Enabled(&iface->options, IFACE_CONF_PROXY)) {
           u_addrtoa(&iface->peer_addr,hisaddr,sizeof(hisaddr));
         if (u_addrempty(&iface->peer_addr)) {          if (u_addrempty(&iface->peer_addr)) {
            Log(LG_IFACE,            Log(LG_IFACE, ("[%s] IFACE: Can't proxy arp for %s",
                ("[%s] IFACE: Can't proxy arp for %s",                b->name, hisaddr));
                b->name, u_addrtoa(&iface->peer_addr,hisaddr,sizeof(hisaddr)))); 
         } else if (GetEther(&iface->peer_addr, &hwa) < 0) {          } else if (GetEther(&iface->peer_addr, &hwa) < 0) {
            Log(LG_IFACE,            Log(LG_IFACE, ("[%s] IFACE: No interface to proxy arp on for %s",
                ("[%s] IFACE: No interface to proxy arp on for %s",                b->name, hisaddr));
                b->name, u_addrtoa(&iface->peer_addr,hisaddr,sizeof(hisaddr)))); 
         } else {          } else {
             ether = (u_char *) LLADDR(&hwa);              ether = (u_char *) LLADDR(&hwa);
             if (ExecCmdNosh(LG_IFACE2, b->name,               if (ExecCmdNosh(LG_IFACE2, b->name, 
                 "%s -S %s %x:%x:%x:%x:%x:%x pub",                  "%s -S %s %x:%x:%x:%x:%x:%x pub",
                PATH_ARP, u_addrtoa(&iface->peer_addr,hisaddr,sizeof(hisaddr)),                PATH_ARP, hisaddr,
                 ether[0], ether[1], ether[2],                  ether[0], ether[1], ether[2],
                 ether[3], ether[4], ether[5]) == 0)                  ether[3], ether[4], ether[5]) == 0)
            iface->proxy_addr = iface->peer_addr;                iface->proxy_addr = iface->peer_addr;
         }          }
     }      }
       
Line 969  IfaceIpIfaceUp(Bund b, int ready) Line 1044  IfaceIpIfaceUp(Bund b, int ready)
         else          else
             ns2buf[0] = '\0';              ns2buf[0] = '\0';
   
        res = ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' '%s' '%s' '%s'",        res = ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' '%s' '%s' '%s' '%s'",
            iface->up_script, iface->ifname, u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)),            iface->up_script, iface->ifname,
             u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)),
             u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)),               u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)), 
             *b->params.authname ? b->params.authname : "-",               *b->params.authname ? b->params.authname : "-", 
            ns1buf, ns2buf, *b->params.peeraddr ? b->params.peeraddr : "-");            ns1buf, ns2buf, *b->params.peeraddr ? b->params.peeraddr : "-",
             b->params.filter_id ? b->params.filter_id : "-");
         if (res != 0) {          if (res != 0) {
             FsmFailure(&b->ipcp.fsm, FAIL_NEGOT_FAILURE);              FsmFailure(&b->ipcp.fsm, FAIL_NEGOT_FAILURE);
             return (-1);              return (-1);
Line 999  IfaceIpIfaceDown(Bund b) Line 1076  IfaceIpIfaceDown(Bund b)
     if (*iface->down_script) {      if (*iface->down_script) {
         char    selfbuf[40],peerbuf[40];          char    selfbuf[40],peerbuf[40];
   
        ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' '%s'",        ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' '%s' '%s'",
            iface->down_script, iface->ifname, u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)),            iface->down_script, iface->ifname,
             u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)),
             u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)),               u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)), 
             *b->params.authname ? b->params.authname : "-",              *b->params.authname ? b->params.authname : "-",
            *b->params.peeraddr ? b->params.peeraddr : "-");            *b->params.peeraddr ? b->params.peeraddr : "-",
             b->params.filter_id ? b->params.filter_id : "-");
     }      }
   
     /* Delete dynamic routes */      /* Delete dynamic routes */
Line 1056  IfaceIpv6IfaceUp(Bund b, int ready) Line 1135  IfaceIpv6IfaceUp(Bund b, int ready)
         iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[1] = 0x0000;          iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[1] = 0x0000;
         iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[2] = 0x0000;          iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[2] = 0x0000;
         iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[3] = 0x0000;          iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[3] = 0x0000;
        iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[4] = ((u_short*)b->ipv6cp.myintid)[0];        bcopy(b->ipv6cp.myintid, &iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[4], sizeof(b->ipv6cp.myintid));
        iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[5] = ((u_short*)b->ipv6cp.myintid)[1];        bcopy(&iface->self_ipv6_addr.u.ip6, &b->ipv6cp.want_addr, sizeof(struct in6_addr));
        iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[6] = ((u_short*)b->ipv6cp.myintid)[2]; 
        iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[7] = ((u_short*)b->ipv6cp.myintid)[3]; 
     } else {      } else {
         u_addrcopy(&iface->conf.self_ipv6_addr, &iface->self_ipv6_addr);          u_addrcopy(&iface->conf.self_ipv6_addr, &iface->self_ipv6_addr);
     }      }
Line 1069  IfaceIpv6IfaceUp(Bund b, int ready) Line 1146  IfaceIpv6IfaceUp(Bund b, int ready)
         iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[1] = 0x0000;          iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[1] = 0x0000;
         iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[2] = 0x0000;          iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[2] = 0x0000;
         iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[3] = 0x0000;          iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[3] = 0x0000;
        iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[4] = ((u_short*)b->ipv6cp.hisintid)[0];        bcopy(b->ipv6cp.hisintid, &iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[4], sizeof(b->ipv6cp.hisintid));
        iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[5] = ((u_short*)b->ipv6cp.hisintid)[1];        bcopy(&iface->peer_ipv6_addr.u.ip6, &b->ipv6cp.peer_addr, sizeof(struct in6_addr));
        iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[6] = ((u_short*)b->ipv6cp.hisintid)[2]; 
        iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[7] = ((u_short*)b->ipv6cp.hisintid)[3]; 
     } else {      } else {
         u_addrcopy(&iface->conf.peer_ipv6_addr, &iface->peer_ipv6_addr);          u_addrcopy(&iface->conf.peer_ipv6_addr, &iface->peer_ipv6_addr);
     }      }
Line 1113  IfaceIpv6IfaceUp(Bund b, int ready) Line 1188  IfaceIpv6IfaceUp(Bund b, int ready)
         char    selfbuf[48],peerbuf[48];          char    selfbuf[48],peerbuf[48];
         int     res;          int     res;
   
        res = ExecCmd(LG_IFACE2, b->name, "%s %s inet6 %s%%%s %s%%%s '%s' '%s'",        res = ExecCmd(LG_IFACE2, b->name, "%s %s inet6 %s%%%s %s%%%s '%s' '%s' '%s'",
             iface->up_script, iface->ifname,               iface->up_script, iface->ifname, 
             u_addrtoa(&iface->self_ipv6_addr, selfbuf, sizeof(selfbuf)), iface->ifname,              u_addrtoa(&iface->self_ipv6_addr, selfbuf, sizeof(selfbuf)), iface->ifname,
             u_addrtoa(&iface->peer_ipv6_addr, peerbuf, sizeof(peerbuf)), iface->ifname,               u_addrtoa(&iface->peer_ipv6_addr, peerbuf, sizeof(peerbuf)), iface->ifname, 
             *b->params.authname ? b->params.authname : "-",              *b->params.authname ? b->params.authname : "-",
            *b->params.peeraddr ? b->params.peeraddr : "-");            *b->params.peeraddr ? b->params.peeraddr : "-",
             b->params.filter_id ? b->params.filter_id : "-");
         if (res != 0) {          if (res != 0) {
             FsmFailure(&b->ipv6cp.fsm, FAIL_NEGOT_FAILURE);              FsmFailure(&b->ipv6cp.fsm, FAIL_NEGOT_FAILURE);
             return (-1);              return (-1);
Line 1145  IfaceIpv6IfaceDown(Bund b) Line 1221  IfaceIpv6IfaceDown(Bund b)
     if (*iface->down_script) {      if (*iface->down_script) {
         char    selfbuf[48],peerbuf[48];          char    selfbuf[48],peerbuf[48];
   
        ExecCmd(LG_IFACE2, b->name, "%s %s inet6 %s%%%s %s%%%s '%s' '%s'",        ExecCmd(LG_IFACE2, b->name, "%s %s inet6 %s%%%s %s%%%s '%s' '%s' '%s'",
             iface->down_script, iface->ifname,               iface->down_script, iface->ifname, 
             u_addrtoa(&iface->self_ipv6_addr, selfbuf, sizeof(selfbuf)), iface->ifname,              u_addrtoa(&iface->self_ipv6_addr, selfbuf, sizeof(selfbuf)), iface->ifname,
             u_addrtoa(&iface->peer_ipv6_addr, peerbuf, sizeof(peerbuf)), iface->ifname,               u_addrtoa(&iface->peer_ipv6_addr, peerbuf, sizeof(peerbuf)), iface->ifname, 
             *b->params.authname ? b->params.authname : "-",              *b->params.authname ? b->params.authname : "-",
            *b->params.peeraddr ? b->params.peeraddr : "-");            *b->params.peeraddr ? b->params.peeraddr : "-",
             b->params.filter_id ? b->params.filter_id : "-");
     }      }
   
     /* Delete dynamic routes */      /* Delete dynamic routes */
Line 1512  IfaceSetCommand(Context ctx, int ac, char *av[], void  Line 1589  IfaceSetCommand(Context ctx, int ac, char *av[], void 
         break;          break;
 #ifdef SIOCSIFDESCR  #ifdef SIOCSIFDESCR
     case SET_DESCR:      case SET_DESCR:
        if (ctx->bund->tmpl)        IfaceFreeDescr(iface);
            Error("Impossible to apply on template"); 
        if (iface->conf.ifdescr != NULL) 
            Freee(iface->conf.ifdescr); 
        iface->conf.ifdescr = NULL; 
        iface->ifdescr = NULL; 
         switch (ac) {          switch (ac) {
           case 0:            case 0:
             return IfaceSetDescr(ctx->bund, "");              return IfaceSetDescr(ctx->bund, "");
             break;              break;
           case 1:            case 1:
             iface->conf.ifdescr = Mstrdup(MB_IFACE, av[0]);              iface->conf.ifdescr = Mstrdup(MB_IFACE, av[0]);
            if (IfaceSetDescr(ctx->bund, av[0]) == 0) {            return IfaceSetDescr(ctx->bund, av[0]);
                iface->ifdescr = iface->conf.ifdescr; 
                return(0); 
            } else 
                return(-1); 
             break;              break;
           default:            default:
             return(-1);              return(-1);
Line 1612  IfaceStat(Context ctx, int ac, char *av[], void *arg) Line 1680  IfaceStat(Context ctx, int ac, char *av[], void *arg)
     Printf("\tName            : %s\r\n", iface->conf.ifname);      Printf("\tName            : %s\r\n", iface->conf.ifname);
 #ifdef SIOCSIFDESCR  #ifdef SIOCSIFDESCR
     Printf("\tDescription     : \"%s\"\r\n",      Printf("\tDescription     : \"%s\"\r\n",
        (iface->conf.ifdescr != NULL) ? iface->conf.ifdescr : "<none>");        (iface->ifdescr != NULL) ? iface->ifdescr : "<none>");
 #endif  #endif
 #ifdef SIOCAIFGROUP  #ifdef SIOCAIFGROUP
     Printf("\tGroup           : %s\r\n", iface->conf.ifgroup);      Printf("\tGroup           : %s\r\n", iface->conf.ifgroup);
Line 1785  IfaceChangeFlags(Bund b, int clear, int set) Line 1853  IfaceChangeFlags(Bund b, int clear, int set)
     struct ifreq ifrq;      struct ifreq ifrq;
     int s, new_flags;      int s, new_flags;
   
    Log(LG_IFACE2, ("[%s] IFACE: Change interface flags: -%d +%d",    Log(LG_IFACE2, ("[%s] IFACE: Change interface %s flags: -%d +%d",
        b->name, clear, set));         b->name, b->iface.ifname, clear, set));
   
     if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {      if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
         Perror("[%s] IFACE: Can't get socket to change interface flags", b->name);          Perror("[%s] IFACE: Can't get socket to change interface flags", b->name);
Line 1795  IfaceChangeFlags(Bund b, int clear, int set) Line 1863  IfaceChangeFlags(Bund b, int clear, int set)
   
     memset(&ifrq, '\0', sizeof(ifrq));      memset(&ifrq, '\0', sizeof(ifrq));
     strlcpy(ifrq.ifr_name, b->iface.ifname, sizeof(ifrq.ifr_name));      strlcpy(ifrq.ifr_name, b->iface.ifname, sizeof(ifrq.ifr_name));
     ifrq.ifr_name[sizeof(ifrq.ifr_name) - 1] = '\0';  
     if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {      if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
        Perror("[%s] IFACE: ioctl(%s, %s)", b->name, b->iface.ifname, "SIOCGIFFLAGS");        Perror("[%s] IFACE: ioctl(SIOCGIFFLAGS, %s)", b->name, b->iface.ifname);
         close(s);          close(s);
         return;          return;
     }      }
Line 1810  IfaceChangeFlags(Bund b, int clear, int set) Line 1877  IfaceChangeFlags(Bund b, int clear, int set)
     ifrq.ifr_flagshigh = new_flags >> 16;      ifrq.ifr_flagshigh = new_flags >> 16;
   
     if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {      if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
        Perror("[%s] IFACE: ioctl(%s, %s)", b->name, b->iface.ifname, "SIOCSIFFLAGS");        Perror("[%s] IFACE: ioctl(SIOCSIFFLAGS, %s)", b->name, b->iface.ifname);
         close(s);          close(s);
         return;          return;
     }      }
Line 1829  add_scope(struct sockaddr *sa, int ifindex) Line 1896  add_scope(struct sockaddr *sa, int ifindex)
   if (!IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) &&    if (!IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) &&
       !IN6_IS_ADDR_MC_LINKLOCAL(&sa6->sin6_addr))        !IN6_IS_ADDR_MC_LINKLOCAL(&sa6->sin6_addr))
     return;      return;
  if (*(u_int16_t *)&sa6->sin6_addr.s6_addr[2] != 0)  if (sa6->sin6_addr.__u6_addr.__u6_addr16[1] != 0)
     return;      return;
  *(u_int16_t *)&sa6->sin6_addr.s6_addr[2] = htons(ifindex);  sa6->sin6_addr.__u6_addr.__u6_addr16[1] = htons(ifindex);
 }  }
 #endif  #endif
   
Line 1902  IfaceChangeAddr(Bund b, int add, struct u_range *self, Line 1969  IfaceChangeAddr(Bund b, int add, struct u_range *self,
   
         res = ioctl(s, add?SIOCAIFADDR_IN6:SIOCDIFADDR_IN6, &ifra6);          res = ioctl(s, add?SIOCAIFADDR_IN6:SIOCDIFADDR_IN6, &ifra6);
         if (res == -1) {          if (res == -1) {
            Perror("[%s] IFACE: %s IPv6 address %s %s failed",                 if (add && errno == EEXIST) {
                b->name, add?"Adding":"Removing", add?"to":"from", b->iface.ifname);                        /* this can happen if the kernel has already automatically added
                            the same link-local address - ignore the error */
                         res = 0;
                 } else {
                         Perror("[%s] IFACE: %s IPv6 address %s %s failed", 
                                 b->name, add?"Adding":"Removing", add?"to":"from", b->iface.ifname);
                 }
         }          }
         break;          break;
   
Line 2070  IfaceNgIpInit(Bund b, int ready) Line 2143  IfaceNgIpInit(Bund b, int ready)
         snprintf(hook, sizeof(hook), "4%d", b->id);          snprintf(hook, sizeof(hook), "4%d", b->id);
   
     } else {      } else {
   
         snprintf(path, sizeof(path), "[%x]:", b->nodeID);          snprintf(path, sizeof(path), "[%x]:", b->nodeID);
         strcpy(hook, NG_PPP_HOOK_INET);          strcpy(hook, NG_PPP_HOOK_INET);
   
Line 2106  IfaceNgIpInit(Bund b, int ready) Line 2178  IfaceNgIpInit(Bund b, int ready)
             Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) {              Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) {
             if (IfaceInitNetflow(b, path, hook,               if (IfaceInitNetflow(b, path, hook, 
                 Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)?1:0,                  Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)?1:0,
                Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)?1:0))                Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)?1:0, 0))
                 goto fail;                  goto fail;
             if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN))              if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN))
                 b->iface.nfin_up = 1;                  b->iface.nfin_up = 1;
Line 2116  IfaceNgIpInit(Bund b, int ready) Line 2188  IfaceNgIpInit(Bund b, int ready)
 #else   /* NG_NETFLOW_CONF_INGRESS */  #else   /* NG_NETFLOW_CONF_INGRESS */
         /* Connect a netflow node if configured */          /* Connect a netflow node if configured */
         if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)) {          if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)) {
            if (IfaceInitNetflow(b, path, hook, 1, 0))            if (IfaceInitNetflow(b, path, hook, 1, 0, 0))
                 goto fail;                  goto fail;
             b->iface.nfin_up = 1;              b->iface.nfin_up = 1;
         }          }
   
         if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) {          if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) {
            if (IfaceInitNetflow(b, path, hook, 0, 1))            if (IfaceInitNetflow(b, path, hook, 0, 1, 0))
                 goto fail;                  goto fail;
             b->iface.nfout_up = 1;              b->iface.nfout_up = 1;
         }          }
Line 2160  IfaceNgIpInit(Bund b, int ready) Line 2232  IfaceNgIpInit(Bund b, int ready)
 #ifdef USE_NG_NETFLOW  #ifdef USE_NG_NETFLOW
 #ifdef NG_NETFLOW_CONF_INGRESS  #ifdef NG_NETFLOW_CONF_INGRESS
         if (b->iface.nfin_up || b->iface.nfout_up)          if (b->iface.nfin_up || b->iface.nfout_up)
            IfaceSetupNetflow(b, b->iface.nfin_up, b->iface.nfout_up);            IfaceSetupNetflow(b, b->iface.nfin_up, b->iface.nfout_up, 0);
 #else /* NG_NETFLOW_CONF_INGRESS */  #else /* NG_NETFLOW_CONF_INGRESS */
         if (b->iface.nfin_up)          if (b->iface.nfin_up)
            IfaceSetupNetflow(b, 1, 0);            IfaceSetupNetflow(b, 1, 0, 0);
   
         if (b->iface.nfout_up)          if (b->iface.nfout_up)
            IfaceSetupNetflow(b, 0, 1);            IfaceSetupNetflow(b, 0, 1, 0);
 #endif /* NG_NETFLOW_CONF_INGRESS */  #endif /* NG_NETFLOW_CONF_INGRESS */
 #endif /* USE_NG_NETFLOW */  #endif /* USE_NG_NETFLOW */
     }      }
Line 2210  IfaceNgIpShutdown(Bund b) Line 2282  IfaceNgIpShutdown(Bund b)
 #ifdef USE_NG_NETFLOW  #ifdef USE_NG_NETFLOW
 #ifdef NG_NETFLOW_CONF_INGRESS  #ifdef NG_NETFLOW_CONF_INGRESS
     if (b->iface.nfin_up || b->iface.nfout_up)      if (b->iface.nfin_up || b->iface.nfout_up)
        IfaceShutdownNetflow(b, b->iface.nfin_up, b->iface.nfout_up);        IfaceShutdownNetflow(b, b->iface.nfin_up, b->iface.nfout_up, 0);
     b->iface.nfin_up = 0;      b->iface.nfin_up = 0;
     b->iface.nfout_up = 0;      b->iface.nfout_up = 0;
 #else /* NG_NETFLOW_CONF_INGRESS */  #else /* NG_NETFLOW_CONF_INGRESS */
     if (b->iface.nfin_up)      if (b->iface.nfin_up)
        IfaceShutdownNetflow(b, 1, 0);        IfaceShutdownNetflow(b, 1, 0, 0);
     b->iface.nfin_up = 0;      b->iface.nfin_up = 0;
     if (b->iface.nfout_up)      if (b->iface.nfout_up)
        IfaceShutdownNetflow(b, 0, 1);        IfaceShutdownNetflow(b, 0, 1, 0);
     b->iface.nfout_up = 0;      b->iface.nfout_up = 0;
 #endif /* NG_NETFLOW_CONF_INGRESS */  #endif /* NG_NETFLOW_CONF_INGRESS */
 #endif  #endif
Line 2263  IfaceNgIpv6Init(Bund b, int ready) Line 2335  IfaceNgIpv6Init(Bund b, int ready)
             b->iface.tee6_up = 1;              b->iface.tee6_up = 1;
         }          }
       
   #ifdef USE_NG_NETFLOW
   #ifdef NG_NETFLOW_CONF_INGRESS
           /* Connect a netflow node if configured */
           if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN) ||
               Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) {
               if (IfaceInitNetflow(b, path, hook, 
                   Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)?1:0,
                   Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)?1:0, 1))
                   goto fail;
               if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN))
                   b->iface.nfin_up = 1;
               if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT))
                   b->iface.nfout_up = 1;
           }
   #else   /* NG_NETFLOW_CONF_INGRESS */
           /* Connect a netflow node if configured */
           if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)) {
               if (IfaceInitNetflow(b, path, hook, 1, 0, 1))
                   goto fail;
               b->iface.nfin_up = 1;
           }
   
           if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) {
               if (IfaceInitNetflow(b, path, hook, 0, 1, 1))
                   goto fail;
               b->iface.nfout_up = 1;
           }
   #endif  /* NG_NETFLOW_CONF_INGRESS */
   #endif  /* USE_NG_NETFLOW */
     }      }
   
   #ifdef USE_NG_BPF
       if (IfaceInitLimits(b, path, hook))
           goto fail;
   #endif
   
     /* Connect graph to the iface node. */      /* Connect graph to the iface node. */
     strcpy(cn.ourhook, hook);      strcpy(cn.ourhook, hook);
     snprintf(cn.path, sizeof(cn.path), "%s:", b->iface.ngname);      snprintf(cn.path, sizeof(cn.path), "%s:", b->iface.ngname);
Line 2276  IfaceNgIpv6Init(Bund b, int ready) Line 2382  IfaceNgIpv6Init(Bund b, int ready)
         goto fail;          goto fail;
     }      }
   
       if (ready) {
   #ifdef USE_NG_NETFLOW
   #ifdef NG_NETFLOW_CONF_INGRESS
           if (b->iface.nfin_up || b->iface.nfout_up)
               IfaceSetupNetflow(b, b->iface.nfin_up, b->iface.nfout_up, 1);
   #else /* NG_NETFLOW_CONF_INGRESS */
           if (b->iface.nfin_up)
               IfaceSetupNetflow(b, 1, 0, 1);
   
           if (b->iface.nfout_up)
               IfaceSetupNetflow(b, 0, 1, 1);
   #endif /* NG_NETFLOW_CONF_INGRESS */
   #endif /* USE_NG_NETFLOW */
       }
   
   #ifdef USE_NG_BPF
       IfaceSetupLimits(b);
   #endif
   
     /* OK */      /* OK */
     return(0);      return(0);
   
Line 2292  IfaceNgIpv6Shutdown(Bund b) Line 2417  IfaceNgIpv6Shutdown(Bund b)
 {  {
     char                path[NG_PATHSIZ];      char                path[NG_PATHSIZ];
   
   #ifdef USE_NG_BPF
       IfaceShutdownLimits(b); /* Limits must shutdown first to save final stats. */
   #endif
     if (b->iface.tee6_up)      if (b->iface.tee6_up)
         IfaceShutdownTee(b, 1);          IfaceShutdownTee(b, 1);
     b->iface.tee6_up = 0;      b->iface.tee6_up = 0;
   #ifdef USE_NG_NETFLOW
   #ifdef NG_NETFLOW_CONF_INGRESS
       if (b->iface.nfin_up || b->iface.nfout_up)
           IfaceShutdownNetflow(b, b->iface.nfin_up, b->iface.nfout_up, 1);
       b->iface.nfin_up = 0;
       b->iface.nfout_up = 0;
   #else /* NG_NETFLOW_CONF_INGRESS */
       if (b->iface.nfin_up)
           IfaceShutdownNetflow(b, 1, 0, 1);
       b->iface.nfin_up = 0;
       if (b->iface.nfout_up)
           IfaceShutdownNetflow(b, 0, 1, 1);
       b->iface.nfout_up = 0;
   #endif /* NG_NETFLOW_CONF_INGRESS */
   #endif
   
     snprintf(path, sizeof(path), "[%x]:", b->nodeID);      snprintf(path, sizeof(path), "[%x]:", b->nodeID);
     NgFuncDisconnect(gLinksCsock, b->name, path, NG_PPP_HOOK_IPV6);      NgFuncDisconnect(gLinksCsock, b->name, path, NG_PPP_HOOK_IPV6);
Line 2381  IfaceSetupNAT(Bund b) Line 2524  IfaceSetupNAT(Bund b)
 {  {
     NatState    const nat = &b->iface.nat;      NatState    const nat = &b->iface.nat;
     char        path[NG_PATHSIZ];      char        path[NG_PATHSIZ];
   #ifdef NG_NAT_DESC_LENGTH
     int k;      int k;
       union {
           u_char buf[sizeof(struct ng_mesg) + sizeof(uint32_t)];
           struct ng_mesg reply;
       } u;
       uint32_t *const nat_id = (uint32_t *)(void *)u.reply.data;
   #endif
   
       snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name);
     if (u_addrempty(&nat->alias_addr)) {      if (u_addrempty(&nat->alias_addr)) {
         snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name);  
         if (NgSendMsg(gLinksCsock, path,          if (NgSendMsg(gLinksCsock, path,
                 NGM_NAT_COOKIE, NGM_NAT_SET_IPADDR,                  NGM_NAT_COOKIE, NGM_NAT_SET_IPADDR,
                 &b->iface.self_addr.addr.u.ip4,                  &b->iface.self_addr.addr.u.ip4,
Line 2396  IfaceSetupNAT(Bund b) Line 2546  IfaceSetupNAT(Bund b)
 #ifdef NG_NAT_DESC_LENGTH  #ifdef NG_NAT_DESC_LENGTH
     /* redirect-port */      /* redirect-port */
     for(k = 0; k < NM_PORT; k++) {      for(k = 0; k < NM_PORT; k++) {
      if(nat->nrpt_id[k]) {      if(nat->nrpt_id[k] == -1) {
         if (NgSendMsg(gLinksCsock, path,          if (NgSendMsg(gLinksCsock, path,
                 NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PORT, &nat->nrpt[k],                  NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PORT, &nat->nrpt[k],
                 sizeof(struct ng_nat_redirect_port)) < 0) {                  sizeof(struct ng_nat_redirect_port)) < 0) {
             Perror("[%s] can't set NAT redirect-port", b->name);              Perror("[%s] can't set NAT redirect-port", b->name);
           } else {
               if (NgRecvMsg(gLinksCsock, &u.reply, sizeof(u), NULL) < 0) {
                   Perror("[%s] can't recv NAT redirect-port message", b->name);
               } else
                   nat->nrpt_id[k] = *nat_id;
         }          }
       }        }
     }      }
     /* redirect-addr */      /* redirect-addr */
     for(k = 0; k < NM_ADDR; k++) {      for(k = 0; k < NM_ADDR; k++) {
      if(nat->nrad_id[k]) {      if(nat->nrad_id[k] == -1) {
         if (NgSendMsg(gLinksCsock, path,          if (NgSendMsg(gLinksCsock, path,
                 NGM_NAT_COOKIE, NGM_NAT_REDIRECT_ADDR, &nat->nrad[k],                  NGM_NAT_COOKIE, NGM_NAT_REDIRECT_ADDR, &nat->nrad[k],
                 sizeof(struct ng_nat_redirect_addr)) < 0) {                  sizeof(struct ng_nat_redirect_addr)) < 0) {
             Perror("[%s] can't set NAT redirect-addr", b->name);              Perror("[%s] can't set NAT redirect-addr", b->name);
           } else {
               if (NgRecvMsg(gLinksCsock, &u.reply, sizeof(u), NULL) < 0) {
                   Perror("[%s] can't recv NAT redirect-addr message", b->name);
               } else
                   nat->nrad_id[k] = *nat_id;
         }          }
       }        }
     }      }
     /* redirect-proto */      /* redirect-proto */
     for(k = 0; k < NM_PROTO; k++) {      for(k = 0; k < NM_PROTO; k++) {
      if(nat->nrpr_id[k]) {      if(nat->nrpr_id[k] == -1) {
         if (NgSendMsg(gLinksCsock, path,          if (NgSendMsg(gLinksCsock, path,
                 NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PROTO, &nat->nrpr[k],                  NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PROTO, &nat->nrpr[k],
                 sizeof(struct ng_nat_redirect_proto)) < 0) {                  sizeof(struct ng_nat_redirect_proto)) < 0) {
             Perror("[%s] can't set NAT redirect-proto", b->name);              Perror("[%s] can't set NAT redirect-proto", b->name);
           } else {
               if (NgRecvMsg(gLinksCsock, &u.reply, sizeof(u), NULL) < 0) {
                   Perror("[%s] can't recv NAT redirect-proto message", b->name);
               } else
                   nat->nrpr_id[k] = *nat_id;
         }          }
       }        }
     }      }
Line 2432  static void Line 2597  static void
 IfaceShutdownNAT(Bund b)  IfaceShutdownNAT(Bund b)
 {  {
     char        path[NG_PATHSIZ];      char        path[NG_PATHSIZ];
   #ifdef NG_NAT_DESC_LENGTH
       NatState    const nat = &b->iface.nat;
       int         k;
   #endif
   
     snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name);      snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name);
     NgFuncShutdownNode(gLinksCsock, b->name, path);      NgFuncShutdownNode(gLinksCsock, b->name, path);
   #ifdef NG_NAT_DESC_LENGTH
       /* redirect-port */
       for(k = 0; k < NM_PORT; k++)
         if(nat->nrpt_id[k] > 0)
           nat->nrpt_id[k] = -1;
       /* redirect-addr */
       for(k = 0; k < NM_ADDR; k++)
         if(nat->nrad_id[k] > 0)
           nat->nrad_id[k] = -1;
       /* redirect-proto */
       for(k = 0; k < NM_PROTO; k++)
         if(nat->nrpr_id[k] > 0)
           nat->nrpr_id[k] = -1;
   #endif
 }  }
 #endif /* USE_NG_NAT */  #endif /* USE_NG_NAT */
   
Line 2580  IfaceShutdownIpacct(Bund b) Line 2763  IfaceShutdownIpacct(Bund b)
   
 #ifdef USE_NG_NETFLOW  #ifdef USE_NG_NETFLOW
 static int  static int
IfaceInitNetflow(Bund b, char *path, char *hook, char in, char out)IfaceInitNetflow(Bund b, char *path, char *hook, char in, char out, int v6)
 {  {
     struct ngm_connect  cn;      struct ngm_connect  cn;
     int nif;      int nif;
   
 #ifdef NG_NETFLOW_CONF_INGRESS  #ifdef NG_NETFLOW_CONF_INGRESS
    nif = gNetflowIface + b->id;    nif = gNetflowIface + b->id*2;
 #else  #else
    nif = gNetflowIface + b->id*2 + out;    nif = gNetflowIface + b->id*4 + out*2;
 #endif  #endif
       nif += v6 ? 1 : 0;
   
    Log(LG_IFACE2, ("[%s] IFACE: Connecting netflow (%s)", b->name, out?"out":"in"));    Log(LG_IFACE2, ("[%s] IFACE: Connecting netflow%s (%s)",
         b->name, v6?"6":"",  out?"out":"in"));
       
     /* Create global ng_netflow(4) node if not yet. */      /* Create global ng_netflow(4) node if not yet. */
     if (gNetflowNodeID == 0) {      if (gNetflowNodeID == 0) {
Line 2634  IfaceInitNetflow(Bund b, char *path, char *hook, char  Line 2819  IfaceInitNetflow(Bund b, char *path, char *hook, char 
 }  }
   
 static int  static int
IfaceSetupNetflow(Bund b, char in, char out)IfaceSetupNetflow(Bund b, char in, char out, int v6)
 {  {
     char path[NG_PATHSIZ];      char path[NG_PATHSIZ];
     struct ng_netflow_setdlt     nf_setdlt;      struct ng_netflow_setdlt     nf_setdlt;
Line 2645  IfaceSetupNetflow(Bund b, char in, char out) Line 2830  IfaceSetupNetflow(Bund b, char in, char out)
     int nif;      int nif;
   
 #ifdef NG_NETFLOW_CONF_INGRESS  #ifdef NG_NETFLOW_CONF_INGRESS
    nif = gNetflowIface + b->id;    nif = gNetflowIface + b->id*2;
 #else  #else
    nif = gNetflowIface + b->id*2 + out;    nif = gNetflowIface + b->id*4 + out*2;
 #endif  #endif
        nif += v6 ? 1 : 0;
 
     /* Configure data link type and interface index. */      /* Configure data link type and interface index. */
     snprintf(path, sizeof(path), "[%x]:", gNetflowNodeID);      snprintf(path, sizeof(path), "[%x]:", gNetflowNodeID);
     nf_setdlt.iface = nif;      nf_setdlt.iface = nif;
Line 2691  fail: Line 2877  fail:
 }  }
   
 static void  static void
IfaceShutdownNetflow(Bund b, char in, char out)IfaceShutdownNetflow(Bund b, char in, char out, int v6)
 {  {
     char        path[NG_PATHSIZ];      char        path[NG_PATHSIZ];
     char        hook[NG_HOOKSIZ];      char        hook[NG_HOOKSIZ];
     int nif;      int nif;
   
 #ifdef NG_NETFLOW_CONF_INGRESS  #ifdef NG_NETFLOW_CONF_INGRESS
    nif = gNetflowIface + b->id;    nif = gNetflowIface + b->id*2;
 #else  #else
    nif = gNetflowIface + b->id*2 + out;    nif = gNetflowIface + b->id*4 + out*2;
 #endif  #endif
       nif += v6 ? 1 : 0;
   
     snprintf(path, NG_PATHSIZ, "[%x]:", gNetflowNodeID);      snprintf(path, NG_PATHSIZ, "[%x]:", gNetflowNodeID);
     snprintf(hook, NG_HOOKSIZ, "%s%d", NG_NETFLOW_HOOK_DATA, nif);      snprintf(hook, NG_HOOKSIZ, "%s%d", NG_NETFLOW_HOOK_DATA, nif);
Line 2970  IfaceSetupLimits(Bund b) Line 3157  IfaceSetupLimits(Bund b)
     struct ngm_connect  cn;      struct ngm_connect  cn;
     int                 i;      int                 i;
           
    hpu = Malloc(MB_IFACE, sizeof(*hpu));    hpu = Malloc(MB_ACL, sizeof(*hpu));
     hp = &hpu->hprog;      hp = &hpu->hprog;
   
     if (b->params.acl_limits[0] || b->params.acl_limits[1]) {      if (b->params.acl_limits[0] || b->params.acl_limits[1]) {
Line 3016  IfaceSetupLimits(Bund b) Line 3203  IfaceSetupLimits(Bund b)
                 }                  }
                                   
                 stathook[0] = 0;                  stathook[0] = 0;
                memset(hpu, 0, sizeof(hpu));                memset(hpu, 0, sizeof(*hpu));
                 /* Prepare filter */                  /* Prepare filter */
                 if (strcasecmp(av[0], "all") == 0) {                  if (strcasecmp(av[0], "all") == 0) {
                     hp->bpf_prog_len = MATCH_PROG_LEN;                      hp->bpf_prog_len = MATCH_PROG_LEN;
Line 3040  IfaceSetupLimits(Bund b) Line 3227  IfaceSetupLimits(Bund b)
                         int             bufbraces;                          int             bufbraces;
   
 #define ACL_BUF_SIZE    256*1024  #define ACL_BUF_SIZE    256*1024
                        buf = Malloc(MB_IFACE, ACL_BUF_SIZE);                        buf = Malloc(MB_ACL, ACL_BUF_SIZE);
                         buf[0] = 0;                          buf[0] = 0;
                         bufbraces = 0;                          bufbraces = 0;
                         while (f) {                          while (f) {
                             char        *b1, *b2, *sbuf;                              char        *b1, *b2, *sbuf;
                            sbuf = Mstrdup(MB_IFACE, f->rule);                            sbuf = Mstrdup(MB_ACL, f->rule);
                             b2 = sbuf;                              b2 = sbuf;
                             b1 = strsep(&b2, " ");                              b1 = strsep(&b2, " ");
                             if (b2 != NULL) {                              if (b2 != NULL) {
Line 3278  IfaceSetupLimits(Bund b) Line 3465  IfaceSetupLimits(Bund b)
                             break;                              break;
                     }                      }
                     if (ss == NULL) {                      if (ss == NULL) {
                        ss = Malloc(MB_IFACE, sizeof(*ss));                        ss = Malloc(MB_ACL, sizeof(*ss));
                         strlcpy(ss->name, l->name, sizeof(ss->name));                          strlcpy(ss->name, l->name, sizeof(ss->name));
                         SLIST_INIT(&ss->src);                          SLIST_INIT(&ss->src);
                         SLIST_INSERT_HEAD(&b->iface.ss[dir], ss, next);                          SLIST_INSERT_HEAD(&b->iface.ss[dir], ss, next);
                     }                      }
                     if (stathook[0]) {                      if (stathook[0]) {
                        sss = Malloc(MB_IFACE, sizeof(*sss));                        sss = Malloc(MB_ACL, sizeof(*sss));
                         strlcpy(sss->hook, stathook, sizeof(sss->hook));                          strlcpy(sss->hook, stathook, sizeof(sss->hook));
                         sss->type = SSSS_IN;                          sss->type = SSSS_IN;
                         SLIST_INSERT_HEAD(&ss->src, sss, next);                          SLIST_INSERT_HEAD(&ss->src, sss, next);
Line 3294  IfaceSetupLimits(Bund b) Line 3481  IfaceSetupLimits(Bund b)
                 for (i = 0; i < 2; i++) {                  for (i = 0; i < 2; i++) {
                     if (inhook[i][0] != 0) {                      if (inhook[i][0] != 0) {
                         if (l->name[0] && !stathook[0]) {                          if (l->name[0] && !stathook[0]) {
                            sss = Malloc(MB_IFACE, sizeof(*sss));                            sss = Malloc(MB_ACL, sizeof(*sss));
                             strlcpy(sss->hook, inhook[i], sizeof(sss->hook));                              strlcpy(sss->hook, inhook[i], sizeof(sss->hook));
                             sss->type = SSSS_MATCH;                              sss->type = SSSS_MATCH;
                             SLIST_INSERT_HEAD(&ss->src, sss, next);                              SLIST_INSERT_HEAD(&ss->src, sss, next);
Line 3392  IfaceGetStats(Bund b, struct svcstat *stat) Line 3579  IfaceGetStats(Bund b, struct svcstat *stat)
                     break;                      break;
             }              }
             if (!ssr) {              if (!ssr) {
                ssr = Malloc(MB_IFACE, sizeof(*ssr));                ssr = Malloc(MB_ACL, sizeof(*ssr));
                 strlcpy(ssr->name, ss->name, sizeof(ssr->name));                  strlcpy(ssr->name, ss->name, sizeof(ssr->name));
                 SLIST_INSERT_HEAD(&stat->stat[dir], ssr, next);                  SLIST_INSERT_HEAD(&stat->stat[dir], ssr, next);
             }              }
Line 3440  IfaceAddStats(struct svcstat *stat1, struct svcstat *s Line 3627  IfaceAddStats(struct svcstat *stat1, struct svcstat *s
                     break;                      break;
             }              }
             if (!ssr1) {              if (!ssr1) {
                ssr1 = Malloc(MB_IFACE, sizeof(*ssr1));                ssr1 = Malloc(MB_ACL, sizeof(*ssr1));
                 strlcpy(ssr1->name, ssr2->name, sizeof(ssr1->name));                  strlcpy(ssr1->name, ssr2->name, sizeof(ssr1->name));
                 SLIST_INSERT_HEAD(&stat1->stat[dir], ssr1, next);                  SLIST_INSERT_HEAD(&stat1->stat[dir], ssr1, next);
             }              }
Line 3486  IfaceSetName(Bund b, const char * ifname) Line 3673  IfaceSetName(Bund b, const char * ifname)
   
     /* Get socket */      /* Get socket */
     if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {      if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
        Log(LG_ERR, ("[%s] IFACE: Can't get socket to set name", b->name));        Perror("[%s] IFACE: Can't get socket to set name", b->name);
         return(-1);          return(-1);
     }      }
   
Line 3498  IfaceSetName(Bund b, const char * ifname) Line 3685  IfaceSetName(Bund b, const char * ifname)
         b->name, iface->ifname, ifname));          b->name, iface->ifname, ifname));
   
     if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) {      if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) {
        Perror("[%s] IFACE: ioctl(%s, SIOCSIFNAME)", b->name, iface->ifname);        if (errno != EEXIST) {
        close(s);            Perror("[%s] IFACE: ioctl(%s, SIOCSIFNAME)", b->name, iface->ifname);
        return(-1);            close(s);
             return(-1);
         }
     }      }
   
     close(s);      close(s);
Line 3512  IfaceSetName(Bund b, const char * ifname) Line 3701  IfaceSetName(Bund b, const char * ifname)
 #ifdef SIOCSIFDESCR  #ifdef SIOCSIFDESCR
 /*  /*
  * IfaceSetDescr()   * IfaceSetDescr()
    *
    * Set/clear our own interface description accessible in console/web interface
    * and kernel level interface description if it is available.
    *
    * Template may contain conversion specifications:
    *
    * %% expands to single % sign;
    * %a for interface local address;
    * %A for peer address;
    * %i for system interface index;
    * %I for interface name;
    * %l for name of bundle's first link
    * %M for peer MAC address of bundle's first link
    * %o for local outer ("physical") address of bundle's first link
    * %O for peer outer ("physical") address of bundle's first link
    * %P for peer outer ("physical") port of bundle's first link
    * %S for interface status (DoD/UP/DOWN)
    * %t for type of bundle's first link (pppoe, pptp, l2tp etc.)
    * %u for self auth name (or dash if self auth name not used)
    * %U for peer auth name (or dash if peer has not authenticated)
  */   */
   
 int  int
IfaceSetDescr(Bund b, const char * ifdescr)IfaceSetDescr(Bund b, const char * template)
 {  {
     IfaceState  const iface = &b->iface;      IfaceState  const iface = &b->iface;
     struct      ifreq ifr;      struct      ifreq ifr;
    int         s, ifdescr_maxlen;    int         s;
     unsigned    int ifdescr_maxlen = 1024; /* used as limit for old kernels */
     char        *newdescr;      char        *newdescr;
    size_t      sz = sizeof(int);    size_t      sz = sizeof(ifdescr_maxlen);
     char        *limit, *ifname;
     const char  *src;
     int         proceed;
     char        buf[64];
   
    if (b->tmpl) {    static      int mib[2] = { -1, 0 }; /* MIB for net.ifdescr_maxlen */
        Log(LG_ERR, ("Impossible ioctl(SIOCSIFDESCR) on template"));    size_t      miblen = sizeof(mib) / sizeof(mib[0]);
        return(-1);
     /*
      * Check whether running kernel supports interface description.
      * Perform the check only once.
      */
     if (mib[0] < 0 && sysctlnametomib("net.ifdescr_maxlen", mib, &miblen) < 0) {
       mib[0] = 0;
       Perror("[%s] IFACE: sysctl net.ifdescr_maxlen  failed", b->name);
     }      }
   
    if (sysctlbyname("net.ifdescr_maxlen", &ifdescr_maxlen, &sz, NULL, 0) < 0) {    /*
        Perror("[%s] IFACE: sysctl net.ifdescr_maxlen  failed", b->name);     * Fetch net.ifdescr_maxlen value every time to catch up with changes
        return(-1);     */
     if (mib[0] && sysctl(mib, 2, &ifdescr_maxlen, &sz, NULL, 0) < 0) {
       /* unexpected error from the kernel, use default value */
       Perror("[%s] IFACE: sysctl net.ifdescr_maxlen  failed", b->name);
       ifdescr_maxlen = 1024;
     }      }
   
    if (ifdescr_maxlen < strlen(ifdescr) + 1) {    newdescr = NULL;
        Log(LG_ERR, ("[%s] IFACE: Description too long, >%d characters",    ifname = iface->ifname;
            b->name, ifdescr_maxlen-1));    if (iface->ifdescr != NULL) {
        return(-1);        Freee(iface->ifdescr);
         iface->ifdescr = NULL;
     }      }
       if ((src = template) != NULL) {
   
         /* Will use Mstrdup() later for iface->ifdescr to free extra memory */
         if ((iface->ifdescr = newdescr = Malloc(MB_IFACE, ifdescr_maxlen)) == NULL) {
           Log(LG_IFACE2, ("[%s] IFACE: no memory for interface %s description",
               b->name, ifname ? ifname : ""));
           return(-1);
         }
   
         /* ifdescr_maxlen includes terminating zero */
         limit = newdescr + ifdescr_maxlen - 1;
   
         /*
          * Perform template expansion
          */
         proceed = 1;
         while (proceed && *src && newdescr < limit) {
           if (*src != '%') {      /* ordinary symbol, just copy it and proceed */
             *newdescr++ = *src++;
             continue;
           }
           if (!*(src+1)) {        /* '%' at the end of template, just copy */
             *newdescr++ = *src++;
             continue;
           }
           switch(*++src) {        /* expand */
             case '%':             /* %% got replaced with single % */
               *newdescr++ = *src;
               break;
   
   #define DST_COPY(a)                             \
     do { const char *temp = a;                    \
       if (temp && *temp) {                        \
         if ((newdescr + strlen (temp)) <= limit) {\
           newdescr = stpcpy (newdescr, temp);     \
         } else {                                  \
           proceed = 0;                            \
         }                                         \
       } else {                                    \
         *newdescr++ = '-';                        \
       }                                           \
     } while(0)
   
             /* self address */
             case 'a':
               {
                 char *sep;
                 u_rangetoa(&iface->self_addr, buf, sizeof(buf));
                 /* cut netmask */
                 if ((sep = strchr(buf, '/')))
                   *sep = '\0';
                 DST_COPY(buf);
               }
               break;
             /* peer address */
             case 'A':
               {
                 u_addrtoa(&iface->peer_addr, buf, sizeof(buf));
                 DST_COPY(buf);
               }
               break;
             /* interface index */
             case 'i':
               {
                 snprintf(buf, sizeof(buf), "%u", iface->ifindex);
                 DST_COPY(buf);
               }
               break;
             /* interface name */
             case 'I':
               DST_COPY(iface->ifname);
               break;
             /* first link name */
             case 'l':
               DST_COPY(b->links[0] ? b->links[0]->name : NULL);
               break;
             /* peer MAC address */
             case 'M':
               if (b->links[0]) {
                 PhysType const pt = b->links[0]->type;
                 if (pt && pt->peermacaddr) {
                   (*pt->peermacaddr)(b->links[0], buf, sizeof(buf));
                   DST_COPY(buf);
                 } else {
                     DST_COPY("-");
                 }
               } else {
                   DST_COPY("-");
               }
               break;
             /* local "physycal" address */
             case 'o':
               if (b->links[0] && PhysGetSelfAddr(b->links[0], buf, sizeof(buf)) == 0) {
                   DST_COPY(buf);
               } else {
                   DST_COPY("-");
               }
               break;
             /* peer "physycal" address */
             case 'O':
               if (b->links[0] && PhysGetPeerAddr(b->links[0], buf, sizeof(buf)) == 0) {
                   DST_COPY(buf);
               } else {
                   DST_COPY("-");
               }
               break;
             /* peer port */
             case 'P':
               if (b->links[0] && PhysGetPeerPort(b->links[0], buf, sizeof(buf)) == 0) {
                   DST_COPY(buf);
               } else {
                   DST_COPY("-");
               }
               break;
             /* interface status */
             case 'S':
               DST_COPY(iface->up ? (iface->dod ? "DoD" : "UP") : "DOWN");
               break;
             /* first link type */
             case 't':
               DST_COPY(b->links[0] ? b->links[0]->type->name : NULL);
               break;
             /* self auth name */
             case 'u':
               DST_COPY(b->links[0] ? b->links[0]->lcp.auth.conf.authname : NULL);
               break;
             /* peer auth name */
             case 'U':
               DST_COPY(b->params.authname);
               break;
   #undef DST_COPY
             default: /* unrecognized specification, just copy */
               *newdescr++ = '%';
               if (newdescr < limit)
                   *newdescr++ = *src;
           } /* switch(*++src) */
           ++src;
         } /* while */
         *newdescr = '\0';
   
         /* includes terminating zero */
         sz = newdescr - iface->ifdescr + 1;
         if ((newdescr = Mstrdup(MB_IFACE, iface->ifdescr)) == NULL) {
           Log(LG_IFACE2, ("[%s] IFACE: no memory for interface %s description",
                           b->name, ifname ? ifname : ""));
           Freee(iface->ifdescr);
           iface->ifdescr = NULL;
           return(-1);
         }
         Freee(iface->ifdescr);
         iface->ifdescr = newdescr;
       } /* template != NULL */
   
       /* Set description of interface */
       if (mib[0] == 0)
           return(0);              /* do not bother kernel if it is too old */
   
       if (ifname == NULL || *ifname == '\0')
           return(0);              /* we have not set system interface name yet */
   
     /* Get socket */      /* Get socket */
     if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {      if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
        Log(LG_ERR, ("[%s] IFACE: Can't get socket to set description", b->name));        Perror("[%s] IFACE: Can't get socket to set description for %s",
                 b->name, ifname);
         return(-1);          return(-1);
     }      }
   
     /* Set description of interface */  
     memset(&ifr, 0, sizeof(ifr));      memset(&ifr, 0, sizeof(ifr));
    strlcpy(ifr.ifr_name, iface->ifname, sizeof(ifr.ifr_name));    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    ifr.ifr_buffer.length = strlen(ifdescr) + 1;
    if (ifr.ifr_buffer.length == 1) {    if (!newdescr || !*newdescr) {       /* empty description or clearing request */
        ifr.ifr_buffer.buffer = newdescr = NULL;        ifr.ifr_buffer.buffer = NULL;
         ifr.ifr_buffer.length = 0;          ifr.ifr_buffer.length = 0;
         Log(LG_IFACE2, ("[%s] IFACE: clearing \"%s\" description",          Log(LG_IFACE2, ("[%s] IFACE: clearing \"%s\" description",
            b->name, iface->ifname));            b->name, ifname));
     } else {      } else {
        newdescr = Mstrdup(MB_IFACE, ifdescr);        ifr.ifr_buffer.length = (unsigned)sz;
         ifr.ifr_buffer.buffer = newdescr;          ifr.ifr_buffer.buffer = newdescr;
         Log(LG_IFACE2, ("[%s] IFACE: setting \"%s\" description to \"%s\"",          Log(LG_IFACE2, ("[%s] IFACE: setting \"%s\" description to \"%s\"",
            b->name, iface->ifname, ifdescr));            b->name, ifname, newdescr));
     }      }
   
     if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) {      if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) {
        Perror("[%s] IFACE: ioctl(%s, SIOCSIFDESCR)", b->name, iface->ifname);        Perror("[%s] IFACE: ioctl(%s, SIOCSIFDESCR, \"%s\")",
        Freee(newdescr);                b->name, ifname, newdescr ? newdescr : "" );
         close(s);          close(s);
         return(-1);          return(-1);
     }      }
     Freee(newdescr);  
     close(s);      close(s);
     return(0);      return(0);
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>