Diff for /embedaddon/mpd/src/pppoe.c between versions 1.1 and 1.1.1.5

version 1.1, 2012/02/21 23:32:47 version 1.1.1.5, 2021/03/17 00:39:23
Line 13 Line 13
 #include "log.h"  #include "log.h"
 #include "util.h"  #include "util.h"
   
   #include <paths.h>
 #include <net/ethernet.h>  #include <net/ethernet.h>
   #include <net/if.h>
 #include <netgraph/ng_message.h>  #include <netgraph/ng_message.h>
 #include <netgraph/ng_pppoe.h>  #include <netgraph/ng_pppoe.h>
 #include <netgraph/ng_ether.h>  #include <netgraph/ng_ether.h>
Line 34 Line 36
   
 #define ETHER_DEFAULT_HOOK      NG_ETHER_HOOK_ORPHAN  #define ETHER_DEFAULT_HOOK      NG_ETHER_HOOK_ORPHAN
   
#define PPPOE_MAXPARENTIFS      1024#ifndef SMALL_SYSTEM
 #define PPPOE_MAXPARENTIFS      4096
 #else
 #define PPPOE_MAXPARENTIFS      32
 #endif
   
 #define MAX_PATH                64      /* XXX should be NG_PATHSIZ */  #define MAX_PATH                64      /* XXX should be NG_PATHSIZ */
 #define MAX_SESSION             64      /* max length of PPPoE session name */  #define MAX_SESSION             64      /* max length of PPPoE session name */
   
   #ifndef PTT_MAX_PAYL                    /* PPP-Max-Payload (RFC4638) */
   #if BYTE_ORDER == BIG_ENDIAN
   #define PTT_MAX_PAYL            (0x0120)
   #else
   #define PTT_MAX_PAYL            (0x2001)
   #endif
   #endif
   
   /* https://tools.ietf.org/html/rfc4937 */
   #if BYTE_ORDER == BIG_ENDIAN
   #define MPD_PTT_CREDITS         (0x0106)
   #define MPD_PTT_METRICS         (0x0107)
   #define MPD_PTT_SEQ_NUMBER      (0x0108)
   #define MPD_PTT_HURL            (0x0111)
   #define MPD_PTT_MOTM            (0x0112)
   #define MPD_PTT_IP_ROUTE_ADD    (0x0121)
   #else
   #define MPD_PTT_CREDITS         (0x0601)
   #define MPD_PTT_METRICS         (0x0701)
   #define MPD_PTT_SEQ_NUMBER      (0x0801)
   #define MPD_PTT_HURL            (0x1101)
   #define MPD_PTT_MOTM            (0x1201)
   #define MPD_PTT_IP_ROUTE_ADD    (0x2101)
   #endif
   
 /* Per link private info */  /* Per link private info */
 struct pppoeinfo {  struct pppoeinfo {
           char            iface[IFNAMSIZ];        /* PPPoE interface name */
         char            path[MAX_PATH];         /* PPPoE node path */          char            path[MAX_PATH];         /* PPPoE node path */
         char            hook[NG_HOOKSIZ];       /* hook on that node */          char            hook[NG_HOOKSIZ];       /* hook on that node */
         char            session[MAX_SESSION];   /* session name */          char            session[MAX_SESSION];   /* session name */
         char            acname[PPPOE_SERVICE_NAME_SIZE];        /* AC name */          char            acname[PPPOE_SERVICE_NAME_SIZE];        /* AC name */
           uint16_t        max_payload;            /* PPP-Max-Payload (RFC4638) */
           int             mac_format;             /* MAC address format */
         u_char          peeraddr[6];            /* Peer MAC address */          u_char          peeraddr[6];            /* Peer MAC address */
         char            real_session[MAX_SESSION]; /* real session name */          char            real_session[MAX_SESSION]; /* real session name */
         char            agent_cid[64];          /* Agent Circuit ID */          char            agent_cid[64];          /* Agent Circuit ID */
         char            agent_rid[64];          /* Agent Remote ID */          char            agent_rid[64];          /* Agent Remote ID */
         u_char          incoming;               /* incoming vs. outgoing */          u_char          incoming;               /* incoming vs. outgoing */
         u_char          opened;                 /* PPPoE opened by phys */          u_char          opened;                 /* PPPoE opened by phys */
           u_char          mp_reply;               /* PPP-Max-Payload reply from server */
         struct optinfo  options;          struct optinfo  options;
         struct PppoeIf  *PIf;                   /* pointer on parent ng_pppoe info */          struct PppoeIf  *PIf;                   /* pointer on parent ng_pppoe info */
         struct PppoeList *list;          struct PppoeList *list;
Line 64  static u_char gNgEtherLoaded = FALSE; Line 99  static u_char gNgEtherLoaded = FALSE;
 enum {  enum {
         SET_IFACE,          SET_IFACE,
         SET_SESSION,          SET_SESSION,
        SET_ACNAME        SET_ACNAME,
         SET_MAX_PAYLOAD,
         SET_MAC_FORMAT
 };  };
   
   /* MAC format options */
   enum {
       MAC_UNFORMATTED = 0,
       MAC_UNIX_LIKE,
       MAC_CISCO_LIKE,
       MAC_IETF
   };
   
 /*  /*
    Invariants:     Invariants:
    ----------     ----------
Line 108  static int PppoeCallingNum(Link l, void *buf, size_t b Line 153  static int PppoeCallingNum(Link l, void *buf, size_t b
 static int      PppoeCalledNum(Link l, void *buf, size_t buf_len);  static int      PppoeCalledNum(Link l, void *buf, size_t buf_len);
 static int      PppoeSelfName(Link l, void *buf, size_t buf_len);  static int      PppoeSelfName(Link l, void *buf, size_t buf_len);
 static int      PppoePeerName(Link l, void *buf, size_t buf_len);  static int      PppoePeerName(Link l, void *buf, size_t buf_len);
   static u_short  PppoeGetMtu(Link l, int conf);
   static u_short  PppoeGetMru(Link l, int conf);
 static void     PppoeCtrlReadEvent(int type, void *arg);  static void     PppoeCtrlReadEvent(int type, void *arg);
 static void     PppoeConnectTimeout(void *arg);  static void     PppoeConnectTimeout(void *arg);
 static void     PppoeStat(Context ctx);  static void     PppoeStat(Context ctx);
static int      PppoeSetCommand(Context ctx, int ac, char *av[], void *arg);static int      PppoeSetCommand(Context ctx, int ac, const char *const av[], const void *arg);
 static int      PppoeOriginated(Link l);  static int      PppoeOriginated(Link l);
 static int      PppoeIsSync(Link l);  static int      PppoeIsSync(Link l);
 static void     PppoeGetNode(Link l);  static void     PppoeGetNode(Link l);
Line 120  static int  PppoeListen(Link l); Line 167  static int  PppoeListen(Link l);
 static int      PppoeUnListen(Link l);  static int      PppoeUnListen(Link l);
 static void     PppoeNodeUpdate(Link l);  static void     PppoeNodeUpdate(Link l);
 static void     PppoeListenEvent(int type, void *arg);  static void     PppoeListenEvent(int type, void *arg);
static int      CreatePppoeNode(struct PppoeIf *PIf, const char *path, const char *hook);static int      CreatePppoeNode(struct PppoeIf *PIf, const char *iface, const char *path, const char *hook);
   
 static void     PppoeDoClose(Link l);  static void     PppoeDoClose(Link l);
   
Line 150  const struct phystype gPppoePhysType = { Line 197  const struct phystype gPppoePhysType = {
     .callednum          = PppoeCalledNum,      .callednum          = PppoeCalledNum,
     .selfname           = PppoeSelfName,      .selfname           = PppoeSelfName,
     .peername           = PppoePeerName,      .peername           = PppoePeerName,
       .getmtu             = PppoeGetMtu,
       .getmru             = PppoeGetMru
 };  };
   
 const struct cmdtab PppoeSetCmds[] = {  const struct cmdtab PppoeSetCmds[] = {
Line 159  const struct cmdtab PppoeSetCmds[] = { Line 208  const struct cmdtab PppoeSetCmds[] = {
           PppoeSetCommand, NULL, 2, (void *)SET_SESSION },            PppoeSetCommand, NULL, 2, (void *)SET_SESSION },
       { "acname {name}",        "Set PPPoE access concentrator name",        { "acname {name}",        "Set PPPoE access concentrator name",
           PppoeSetCommand, NULL, 2, (void *)SET_ACNAME },            PppoeSetCommand, NULL, 2, (void *)SET_ACNAME },
      { NULL },#ifdef NGM_PPPOE_SETMAXP_COOKIE
       { "max-payload {size}",   "Set PPP-Max-Payload tag",
           PppoeSetCommand, NULL, 2, (void *)SET_MAX_PAYLOAD },
 #endif
       { "mac-format {format}",  "Set RADIUS attribute 31 MAC format",
           PppoeSetCommand, NULL, 2, (void *)SET_MAC_FORMAT },
       { NULL, NULL, NULL, NULL, 0, NULL }
 };  };
   
 /*   /* 
Line 183  struct PppoeIf { Line 238  struct PppoeIf {
     SLIST_HEAD(, PppoeList) list;      SLIST_HEAD(, PppoeList) list;
 };  };
   
int PppoeIfCount=0;static struct PppoeIf PppoeIfs[PPPOE_MAXPARENTIFS];
struct PppoeIf PppoeIfs[PPPOE_MAXPARENTIFS]; 
   
   struct tagname {
       int         tag;
       const char  *name;
   };
   
   static const struct tagname tag2str[] = {
       { PTT_EOL, "End-Of-List" },
       { PTT_SRV_NAME, "Service-Name" },
       { PTT_AC_NAME, "AC-Name" },
       { PTT_HOST_UNIQ, "Host-Uniq" },
       { PTT_AC_COOKIE, "AC-Cookie" },
       { PTT_VENDOR, "Vendor-Specific" },
       { PTT_RELAY_SID, "Relay-Session-Id" },
       { PTT_MAX_PAYL, "PPP-Max-Payload" },
       { PTT_SRV_ERR, "Service-Name-Error" },
       { PTT_SYS_ERR, "AC-System-Error" },
       { PTT_GEN_ERR, "Generic-Error" },
       /* RFC 4937 */
       { MPD_PTT_CREDITS, "Credits" },
       { MPD_PTT_METRICS, "Metrics" },
       { MPD_PTT_SEQ_NUMBER, "Sequence Number" },
       { MPD_PTT_HURL, "HURL" },
       { MPD_PTT_MOTM, "MOTM" },
       { MPD_PTT_IP_ROUTE_ADD, "IP_Route_Add" },
       { 0, "UNKNOWN" }
   };
   #define NUM_TAG_NAMES   (sizeof(tag2str) / sizeof(*tag2str))
   
   
 /*  /*
  * PppoeInit()   * PppoeInit()
  *   *
Line 200  PppoeInit(Link l) Line 283  PppoeInit(Link l)
         pe = (PppoeInfo)(l->info = Malloc(MB_PHYS, sizeof(*pe)));          pe = (PppoeInfo)(l->info = Malloc(MB_PHYS, sizeof(*pe)));
         pe->incoming = 0;          pe->incoming = 0;
         pe->opened = 0;          pe->opened = 0;
           snprintf(pe->iface, sizeof(pe->iface), "undefined");
         snprintf(pe->path, sizeof(pe->path), "undefined:");          snprintf(pe->path, sizeof(pe->path), "undefined:");
         snprintf(pe->hook, sizeof(pe->hook), "undefined");          snprintf(pe->hook, sizeof(pe->hook), "undefined");
         snprintf(pe->session, sizeof(pe->session), "*");          snprintf(pe->session, sizeof(pe->session), "*");
Line 208  PppoeInit(Link l) Line 292  PppoeInit(Link l)
         pe->agent_cid[0] = 0;          pe->agent_cid[0] = 0;
         pe->agent_rid[0] = 0;          pe->agent_rid[0] = 0;
         pe->PIf = NULL;          pe->PIf = NULL;
           pe->max_payload = 0;
           pe->mac_format = MAC_UNFORMATTED;
           pe->mp_reply = 0;
   
         /* Done */          /* Done */
         return(0);          return(0);
Line 322  PppoeOpen(Link l) Line 409  PppoeOpen(Link l)
                     l->name, path, cn.ourhook, cn.path, cn.peerhook);                      l->name, path, cn.ourhook, cn.path, cn.peerhook);
                 goto fail2;                  goto fail2;
         }          }
           
   #ifdef NGM_PPPOE_SETMAXP_COOKIE
           if (pe->max_payload > 0)
               Log(LG_PHYS, ("[%s] PPPoE: Set PPP-Max-Payload to '%u'",
                   l->name, pe->max_payload));
           /* Tell the PPPoE node to set PPP-Max-Payload value (unset if 0). */
           if (NgSendMsg(pe->PIf->csock, path, NGM_PPPOE_COOKIE, NGM_PPPOE_SETMAXP,
               &pe->max_payload, sizeof(uint16_t)) < 0) {
                   Perror("[%s] PPPoE can't set PPP-Max-Payload value", l->name);
                   goto fail2;
           }
   #endif
   
         Log(LG_PHYS, ("[%s] PPPoE: Connecting to '%s'", l->name, pe->session));          Log(LG_PHYS, ("[%s] PPPoE: Connecting to '%s'", l->name, pe->session));
                   
         /* Tell the PPPoE node to try to connect to a server. */          /* Tell the PPPoE node to try to connect to a server. */
        memset(idata, 0, sizeof(idata));        memset(idata, 0, sizeof(struct ngpppoe_init_data));
         strlcpy(idata->hook, session_hook, sizeof(idata->hook));          strlcpy(idata->hook, session_hook, sizeof(idata->hook));
         idata->data_len = strlen(pe->session);          idata->data_len = strlen(pe->session);
         strncpy(idata->data, pe->session, MAX_SESSION);          strncpy(idata->data, pe->session, MAX_SESSION);
Line 346  PppoeOpen(Link l) Line 445  PppoeOpen(Link l)
         strlcpy(pe->real_session, pe->session, sizeof(pe->real_session));          strlcpy(pe->real_session, pe->session, sizeof(pe->real_session));
         pe->agent_cid[0] = 0;          pe->agent_cid[0] = 0;
         pe->agent_rid[0] = 0;          pe->agent_rid[0] = 0;
           pe->mp_reply = 0;
         return;          return;
   
 fail3:  fail3:
Line 428  PppoeDoClose(Link l) Line 528  PppoeDoClose(Link l)
         pi->real_session[0] = 0;          pi->real_session[0] = 0;
         pi->agent_cid[0] = 0;          pi->agent_cid[0] = 0;
         pi->agent_rid[0] = 0;          pi->agent_rid[0] = 0;
           pi->mp_reply = 0;
 }  }
   
 /*  /*
Line 439  static void Line 540  static void
 PppoeCtrlReadEvent(int type, void *arg)  PppoeCtrlReadEvent(int type, void *arg)
 {  {
         union {          union {
   #ifdef NGM_PPPOE_SETMAXP_COOKIE
               u_char buf[sizeof(struct ng_mesg) + sizeof(struct ngpppoe_maxp)];
   #else
             u_char buf[sizeof(struct ng_mesg) + sizeof(struct ngpppoe_sts)];              u_char buf[sizeof(struct ng_mesg) + sizeof(struct ngpppoe_sts)];
   #endif
             struct ng_mesg resp;              struct ng_mesg resp;
         } u;          } u;
         char path[NG_PATHSIZ];          char path[NG_PATHSIZ];
Line 447  PppoeCtrlReadEvent(int type, void *arg) Line 552  PppoeCtrlReadEvent(int type, void *arg)
         PppoeInfo pi = NULL;          PppoeInfo pi = NULL;
                   
         struct PppoeIf  *PIf = (struct PppoeIf*)arg;          struct PppoeIf  *PIf = (struct PppoeIf*)arg;
        
         (void)type;
         /* Read control message. */          /* Read control message. */
         if (NgRecvMsg(PIf->csock, &u.resp, sizeof(u), path) < 0) {          if (NgRecvMsg(PIf->csock, &u.resp, sizeof(u), path) < 0) {
                 Perror("PPPoE: error reading message from \"%s\"", path);                  Perror("PPPoE: error reading message from \"%s\"", path);
Line 463  PppoeCtrlReadEvent(int type, void *arg) Line 569  PppoeCtrlReadEvent(int type, void *arg)
             case NGM_PPPOE_SUCCESS:              case NGM_PPPOE_SUCCESS:
             case NGM_PPPOE_FAIL:              case NGM_PPPOE_FAIL:
             case NGM_PPPOE_CLOSE:              case NGM_PPPOE_CLOSE:
   #ifdef NGM_PPPOE_SETMAXP_COOKIE
               case NGM_PPPOE_SETMAXP:
   #endif
             {              {
                 char    ppphook[NG_HOOKSIZ];                  char    ppphook[NG_HOOKSIZ];
                 char    *linkname, *rest;                  char    *linkname, *rest;
Line 505  PppoeCtrlReadEvent(int type, void *arg) Line 614  PppoeCtrlReadEvent(int type, void *arg)
         /* Decode message. */          /* Decode message. */
         switch (u.resp.header.cmd) {          switch (u.resp.header.cmd) {
             case NGM_PPPOE_SESSIONID: /* XXX: I do not know what to do with this? */              case NGM_PPPOE_SESSIONID: /* XXX: I do not know what to do with this? */
                   Log(LG_PHYS3, ("PPPoE: rec'd SESSIONID %u from \"%s\"",
                     ntohs((uint16_t)u.resp.data), path));
                 break;                  break;
             case NGM_PPPOE_SUCCESS:              case NGM_PPPOE_SUCCESS:
                 Log(LG_PHYS, ("[%s] PPPoE: connection successful", l->name));                  Log(LG_PHYS, ("[%s] PPPoE: connection successful", l->name));
Line 530  PppoeCtrlReadEvent(int type, void *arg) Line 641  PppoeCtrlReadEvent(int type, void *arg)
                 Log(LG_PHYS, ("PPPoE: rec'd ACNAME \"%s\"",                  Log(LG_PHYS, ("PPPoE: rec'd ACNAME \"%s\"",
                   ((struct ngpppoe_sts *)u.resp.data)->hook));                    ((struct ngpppoe_sts *)u.resp.data)->hook));
                 break;                  break;
   #ifdef NGM_PPPOE_SETMAXP_COOKIE
               case NGM_PPPOE_SETMAXP:
               {
                   struct ngpppoe_maxp *maxp;
                   
                   maxp = ((struct ngpppoe_maxp *)(void *)u.resp.data);
                   Log(LG_PHYS, ("[%s] PPPoE: rec'd PPP-Max-Payload '%u'",
                     l->name, maxp->data));
                   if (pi->max_payload > 0) {
                       if (pi->max_payload == maxp->data)
                           pi->mp_reply = 1;
                       else
                           Log(LG_PHYS,
                             ("[%s] PPPoE: sent and returned values are not equal",
                             l->name));
                   } else
                       Log(LG_PHYS, ("[%s] PPPoE: server sent tag PPP-Max-Payload"
                         " without request from the client",
                         l->name));
                   break;
               }
   #endif
   #ifdef NGM_PPPOE_PADM_COOKIE
               case NGM_PPPOE_HURL:
                   Log(LG_PHYS, ("PPPoE: rec'd HURL \"%s\"",
                     ((struct ngpppoe_padm *)u.resp.data)->msg));
                   break;
               case NGM_PPPOE_MOTM:
                   Log(LG_PHYS, ("PPPoE: rec'd MOTM \"%s\"",
                     ((struct ngpppoe_padm *)u.resp.data)->msg));
                   break;
   #endif
             default:              default:
                 Log(LG_PHYS, ("PPPoE: rec'd command %lu from \"%s\"",                  Log(LG_PHYS, ("PPPoE: rec'd command %lu from \"%s\"",
                     (u_long)u.resp.header.cmd, path));                      (u_long)u.resp.header.cmd, path));
Line 546  PppoeStat(Context ctx) Line 689  PppoeStat(Context ctx)
         const PppoeInfo pe = (PppoeInfo)ctx->lnk->info;          const PppoeInfo pe = (PppoeInfo)ctx->lnk->info;
         char    buf[32];          char    buf[32];
   
           switch (pe->mac_format) {
               case MAC_UNFORMATTED:
                   sprintf(buf, "unformatted");
                   break;
               case MAC_UNIX_LIKE:
                   sprintf(buf, "unix-like");
                   break;
               case MAC_CISCO_LIKE:
                   sprintf(buf, "cisco-like");
                   break;
               case MAC_IETF:
                   sprintf(buf, "ietf");
                   break;
               default:
                   sprintf(buf, "unknown");
                   break;
           }
   
         Printf("PPPoE configuration:\r\n");          Printf("PPPoE configuration:\r\n");
           Printf("\tIface Name   : %s\r\n", pe->iface);
         Printf("\tIface Node   : %s\r\n", pe->path);          Printf("\tIface Node   : %s\r\n", pe->path);
         Printf("\tIface Hook   : %s\r\n", pe->hook);          Printf("\tIface Hook   : %s\r\n", pe->hook);
         Printf("\tSession      : %s\r\n", pe->session);          Printf("\tSession      : %s\r\n", pe->session);
   #ifdef NGM_PPPOE_SETMAXP_COOKIE
           Printf("\tMax-Payload  : %u\r\n", pe->max_payload);
   #endif
           Printf("\tMAC format   : %s\r\n", buf);
         Printf("PPPoE status:\r\n");          Printf("PPPoE status:\r\n");
         if (ctx->lnk->state != PHYS_STATE_DOWN) {          if (ctx->lnk->state != PHYS_STATE_DOWN) {
             Printf("\tOpened       : %s\r\n", (pe->opened?"YES":"NO"));              Printf("\tOpened       : %s\r\n", (pe->opened?"YES":"NO"));
Line 557  PppoeStat(Context ctx) Line 723  PppoeStat(Context ctx)
             PppoePeerMacAddr(ctx->lnk, buf, sizeof(buf));              PppoePeerMacAddr(ctx->lnk, buf, sizeof(buf));
             Printf("\tCurrent peer : %s\r\n", buf);              Printf("\tCurrent peer : %s\r\n", buf);
             Printf("\tSession      : %s\r\n", pe->real_session);              Printf("\tSession      : %s\r\n", pe->real_session);
               Printf("\tMax-Payload  : %s\r\n", (pe->mp_reply?"YES":"NO"));
             Printf("\tCircuit-ID   : %s\r\n", pe->agent_cid);              Printf("\tCircuit-ID   : %s\r\n", pe->agent_cid);
             Printf("\tRemote-ID    : %s\r\n", pe->agent_rid);              Printf("\tRemote-ID    : %s\r\n", pe->agent_rid);
         }          }
Line 579  PppoeOriginated(Link l) Line 746  PppoeOriginated(Link l)
 static int  static int
 PppoeIsSync(Link l)  PppoeIsSync(Link l)
 {  {
           (void)l;
         return (1);          return (1);
 }  }
   
Line 587  PppoePeerMacAddr(Link l, void *buf, size_t buf_len) Line 755  PppoePeerMacAddr(Link l, void *buf, size_t buf_len)
 {  {
         PppoeInfo       const pppoe = (PppoeInfo)l->info;          PppoeInfo       const pppoe = (PppoeInfo)l->info;
   
        snprintf(buf, buf_len, "%02x:%02x:%02x:%02x:%02x:%02x",        if (buf_len < 18)
            pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],                 return (1);
            pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]);        ether_ntoa_r((struct ether_addr *)pppoe->peeraddr, buf);
 
         return (0);          return (0);
 }  }
   
Line 598  static int Line 765  static int
 PppoePeerIface(Link l, void *buf, size_t buf_len)  PppoePeerIface(Link l, void *buf, size_t buf_len)
 {  {
         PppoeInfo       const pppoe = (PppoeInfo)l->info;          PppoeInfo       const pppoe = (PppoeInfo)l->info;
         char iface[IFNAMSIZ];  
   
        strlcpy(iface, pppoe->path, sizeof(iface));        strlcpy(buf, pppoe->iface, buf_len);
        if (iface[strlen(iface) - 1] == ':') 
                iface[strlen(iface) - 1] = '\0'; 
        strlcpy(buf, iface, buf_len); 
         return (0);          return (0);
 }  }
   
Line 613  PppoeCallingNum(Link l, void *buf, size_t buf_len) Line 776  PppoeCallingNum(Link l, void *buf, size_t buf_len)
         PppoeInfo       const pppoe = (PppoeInfo)l->info;          PppoeInfo       const pppoe = (PppoeInfo)l->info;
   
         if (pppoe->incoming) {          if (pppoe->incoming) {
            snprintf(buf, buf_len, "%02x%02x%02x%02x%02x%02x",            switch (pppoe->mac_format) {
                pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],                 case MAC_UNFORMATTED:
                pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]);                    snprintf(buf, buf_len, "%02x%02x%02x%02x%02x%02x",
                     pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],
                     pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]);
                     break;
                 case MAC_UNIX_LIKE:
                     ether_ntoa_r((struct ether_addr *)pppoe->peeraddr, buf);
                     break;
                 case MAC_CISCO_LIKE:
                     snprintf(buf, buf_len, "%02x%02x.%02x%02x.%02x%02x",
                     pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],
                     pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]);
                     break;
                 case MAC_IETF:
                     snprintf(buf, buf_len, "%02x-%02x-%02x-%02x-%02x-%02x",
                     pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],
                     pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]);
                     break;
                 default:
                     sprintf(buf, "unknown");
                     return(-1);
                     break;
             }
         } else {          } else {
             strlcpy(buf, pppoe->real_session, buf_len);              strlcpy(buf, pppoe->real_session, buf_len);
         }          }
Line 629  PppoeCalledNum(Link l, void *buf, size_t buf_len) Line 813  PppoeCalledNum(Link l, void *buf, size_t buf_len)
         PppoeInfo       const pppoe = (PppoeInfo)l->info;          PppoeInfo       const pppoe = (PppoeInfo)l->info;
   
         if (!pppoe->incoming) {          if (!pppoe->incoming) {
            snprintf(buf, buf_len, "%02x%02x%02x%02x%02x%02x",            switch (pppoe->mac_format) {
                pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],                 case MAC_UNFORMATTED:
                pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]);                    snprintf(buf, buf_len, "%02x%02x%02x%02x%02x%02x",
                     pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],
                     pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]);
                     break;
                 case MAC_UNIX_LIKE:
                     ether_ntoa_r((struct ether_addr *)pppoe->peeraddr, buf);
                     break;
                 case MAC_CISCO_LIKE:
                     snprintf(buf, buf_len, "%02x%02x.%02x%02x.%02x%02x",
                     pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],
                     pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]);
                     break;
                 case MAC_IETF:
                     snprintf(buf, buf_len, "%02x-%02x-%02x-%02x-%02x-%02x",
                     pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],
                     pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]);
                     break;
                 default:
                     sprintf(buf, "unknown");
                     return(-1);
                     break;
             }
         } else {          } else {
             strlcpy(buf, pppoe->real_session, buf_len);              strlcpy(buf, pppoe->real_session, buf_len);
         }          }
Line 659  PppoePeerName(Link l, void *buf, size_t buf_len) Line 864  PppoePeerName(Link l, void *buf, size_t buf_len)
         return (0);          return (0);
 }  }
   
   static u_short
   PppoeGetMtu(Link l, int conf)
   {
           PppoeInfo       const pppoe = (PppoeInfo)l->info;
   
           if (pppoe->max_payload > 0 && pppoe->mp_reply > 0)
               return (pppoe->max_payload);
           else
               if (conf == 0)
                   return (l->type->mtu);
               else
                   return (l->conf.mtu);
   }
   
   static u_short
   PppoeGetMru(Link l, int conf)
   {
           PppoeInfo       const pppoe = (PppoeInfo)l->info;
   
           if (pppoe->max_payload > 0 && pppoe->mp_reply > 0)
               return (pppoe->max_payload);
           else
               if (conf == 0)
                   return (l->type->mru);
               else
                   return (l->conf.mru);
   }
   
 static int   static int 
CreatePppoeNode(struct PppoeIf *PIf, const char *path, const char *hook)CreatePppoeNode(struct PppoeIf *PIf, const char *iface, const char *path, const char *hook)
 {  {
         union {          union {
                 u_char          buf[sizeof(struct ng_mesg) + 2048];                  u_char          buf[sizeof(struct ng_mesg) + 2048];
Line 669  CreatePppoeNode(struct PppoeIf *PIf, const char *path, Line 902  CreatePppoeNode(struct PppoeIf *PIf, const char *path,
         struct ng_mesg *resp;          struct ng_mesg *resp;
         const struct hooklist *hlist;          const struct hooklist *hlist;
         const struct nodeinfo *ninfo;          const struct nodeinfo *ninfo;
        int f;        uint32_t f;
   
         /* Make sure interface is up. */          /* Make sure interface is up. */
        char iface[IFNAMSIZ];        if (IfaceSetFlag(iface, IFF_UP) != 0) {
                Perror("[%s] PPPoE: can't bring up interface", iface);
        strlcpy(iface, path, sizeof(iface)); 
        if (iface[strlen(iface) - 1] == ':') 
                iface[strlen(iface) - 1] = '\0'; 
        if (ExecCmdNosh(LG_PHYS2, iface, "%s %s up", PATH_IFCONFIG, iface) != 0) { 
                Log(LG_ERR, ("PPPoE: can't bring up interface %s", 
                    iface)); 
                 return (0);                  return (0);
         }          }
   
         /* Create a new netgraph node */          /* Create a new netgraph node */
         if (NgMkSockNode(NULL, &PIf->csock, &PIf->dsock) < 0) {          if (NgMkSockNode(NULL, &PIf->csock, &PIf->dsock) < 0) {
                 Perror("[%s] PPPoE: can't create ctrl socket", iface);                  Perror("[%s] PPPoE: can't create ctrl socket", iface);
                return(0);                return (0);
         }          }
         (void)fcntl(PIf->csock, F_SETFD, 1);          (void)fcntl(PIf->csock, F_SETFD, 1);
         (void)fcntl(PIf->dsock, F_SETFD, 1);          (void)fcntl(PIf->dsock, F_SETFD, 1);
Line 716  CreatePppoeNode(struct PppoeIf *PIf, const char *path, Line 942  CreatePppoeNode(struct PppoeIf *PIf, const char *path,
                 }                  }
   
                 /* Look for NG_ETHER_NODE_TYPE. */                  /* Look for NG_ETHER_NODE_TYPE. */
                tlist = (const struct typelist*) resp->data;                tlist = (const struct typelist*)(void *)resp->data;
                 for (f = 0; f < tlist->numtypes; f++)                  for (f = 0; f < tlist->numtypes; f++)
                         if (strncmp(tlist->typeinfo[f].type_name,                          if (strncmp(tlist->typeinfo[f].type_name,
                             NG_ETHER_NODE_TYPE,                              NG_ETHER_NODE_TYPE,
Line 755  CreatePppoeNode(struct PppoeIf *PIf, const char *path, Line 981  CreatePppoeNode(struct PppoeIf *PIf, const char *path,
                 return (0);                  return (0);
         }          }
   
        hlist = (const struct hooklist *)resp->data;        hlist = (const struct hooklist *)(void *)resp->data;
         ninfo = &hlist->nodeinfo;          ninfo = &hlist->nodeinfo;
   
         /* Make sure we've got the right type of node. */          /* Make sure we've got the right type of node. */
Line 816  CreatePppoeNode(struct PppoeIf *PIf, const char *path, Line 1042  CreatePppoeNode(struct PppoeIf *PIf, const char *path,
                 snprintf(path2, sizeof(path2), "%s%s", path, hook);                  snprintf(path2, sizeof(path2), "%s%s", path, hook);
                 /* Get pppoe node ID */                  /* Get pppoe node ID */
                 if ((PIf->node_id = NgGetNodeID(PIf->csock, path2)) == 0) {                  if ((PIf->node_id = NgGetNodeID(PIf->csock, path2)) == 0) {
                        Perror("[%s] Cannot get pppoe node id", iface);                        Perror("[%s] Cannot get %s node id", iface,
                             NG_PPPOE_NODE_TYPE);
                         close(PIf->csock);                          close(PIf->csock);
                         close(PIf->dsock);                          close(PIf->dsock);
                         return (0);                          return (0);
Line 884  get_vs_tag(const struct pppoe_hdr* ph, uint32_t idx) Line 1111  get_vs_tag(const struct pppoe_hdr* ph, uint32_t idx)
                         return (NULL);                          return (NULL);
                 if (pt->tag_type == PTT_VENDOR &&                  if (pt->tag_type == PTT_VENDOR &&
                     ntohs(pt->tag_len) >= 4 &&                      ntohs(pt->tag_len) >= 4 &&
                    *(const uint32_t*)(pt + 1) == idx)                    *(const uint32_t*)(const void *)(pt + 1) == idx)
                         return (pt);                          return (pt);
   
                 pt = (const struct pppoe_tag*)ptn;                  pt = (const struct pppoe_tag*)ptn;
Line 894  get_vs_tag(const struct pppoe_hdr* ph, uint32_t idx) Line 1121  get_vs_tag(const struct pppoe_hdr* ph, uint32_t idx)
 }  }
   
 static void  static void
   print_tags(const struct pppoe_hdr* ph)
   {
           const char *const end = ((const char *)(ph + 1))
                       + ntohs(ph->length);
           const struct pppoe_tag *pt = (const void *)(ph + 1);
           const char *ptn;
           const void *v;
           char buf[1024], tag[32];
           size_t len, k;
   
           /*
            * Keep processing tags while a tag header will still fit.
            */
           while((const char*)(pt + 1) <= end) {
                   /*
                    * If the tag data would go past the end of the packet, abort.
                    */
                   v = pt + 1;
                   ptn = (((const char *)(pt + 1)) + ntohs(pt->tag_len));
                   if (ptn > end)
                           return;
                   len = ntohs(pt->tag_len);
                   buf[0] = 0;
                   switch (pt->tag_type) {
                       case PTT_EOL:
                           if (len != 0)
                               sprintf(buf, "TAG_LENGTH is not zero!");
                           break;
                       case PTT_SRV_NAME:
                           if (len >= sizeof(buf))
                               len = sizeof(buf)-1;
                           memcpy(buf, pt + 1, len);
                           buf[len] = 0;
                           if (len == 0)
                               sprintf(buf, "Any service is acceptable");
                           break;
                       case PTT_AC_NAME:
                           if (len >= sizeof(buf))
                               len = sizeof(buf)-1;
                           memcpy(buf, pt + 1, len);
                           buf[len] = 0;
                           break;
                       case PTT_HOST_UNIQ:
                       case PTT_AC_COOKIE:
                       case PTT_RELAY_SID:
                           snprintf(buf, sizeof(buf), "0x%s", Bin2Hex(v, len));
                           break;
                       case PTT_VENDOR:
                           if (len >= 4) {
                               if ((const uint8_t)*(const uint8_t*)v != 0) {
                                   snprintf(buf, sizeof(buf),
                                       "First byte of VENDOR is not zero! 0x%s",
                                       Bin2Hex(v, len));
                               } else {
                                   snprintf(buf, sizeof(buf), "0x%s 0x%s",
                                   Bin2Hex(v, 4),
                                   Bin2Hex((const uint8_t*)v + 4, len - 4));
                               }
                           } else {
                               sprintf(buf, "TAG_LENGTH must be >= 4 !");
                           }
                           break;
                       case PTT_MAX_PAYL:
                           if (len != 2) {
                               sprintf(buf, "TAG_LENGTH is not 2!");
                           } else {
                               sprintf(buf, "%u", *(const uint16_t*)(const void *)(pt + 1));
                           }
                           break;
                       case PTT_SRV_ERR:
                           if (len > 0 && (const char *)(pt + 1)+4 !=0) {
                               if (len >= sizeof(buf))
                                   len = sizeof(buf)-1;
                               memcpy(buf, pt + 1, len);
                               buf[len] = 0;
                           }
                           break;
                       case PTT_SYS_ERR:
                       case PTT_GEN_ERR:
                           if (len >= sizeof(buf))
                               len = sizeof(buf)-1;
                           memcpy(buf, pt + 1, len);
                           buf[len] = 0;
                           break;
                       case MPD_PTT_CREDITS:
                       case MPD_PTT_METRICS:
                       case MPD_PTT_SEQ_NUMBER:
                       case MPD_PTT_HURL:
                       case MPD_PTT_MOTM:
                       case MPD_PTT_IP_ROUTE_ADD:
                           sprintf(buf, "Not implemented");
                           break;
                       default:
                           sprintf(buf, "0x%04x", pt->tag_type);
                           break;
                   }
                   /* First check our stat list for known tags */
                   for (k = 0; k < NUM_TAG_NAMES; k++) {
                       if (pt->tag_type == tag2str[k].tag) {
                           sprintf(tag, "%s", tag2str[k].name);
                           break;
                       }
                   }
                   Log(LG_PHYS3, ("TAG: %s, Value: %s", tag, buf));
                   pt = (const struct pppoe_tag*)ptn;
           }
   }
   
   static void
 PppoeListenEvent(int type, void *arg)  PppoeListenEvent(int type, void *arg)
 {  {
         int                     k, sz;          int                     k, sz;
Line 922  PppoeListenEvent(int type, void *arg) Line 1258  PppoeListenEvent(int type, void *arg)
         } u;          } u;
         struct ngpppoe_init_data *const idata = &u.poeid;          struct ngpppoe_init_data *const idata = &u.poeid;
   
           (void)type;
         switch (sz = NgRecvData(PIf->dsock, response, sizeof(response), rhook)) {          switch (sz = NgRecvData(PIf->dsock, response, sizeof(response), rhook)) {
           case -1:            case -1:
             Log(LG_ERR, ("NgRecvData: %d", sz));              Log(LG_ERR, ("NgRecvData: %d", sz));
Line 938  PppoeListenEvent(int type, void *arg) Line 1275  PppoeListenEvent(int type, void *arg)
   
         session = rhook + 7;          session = rhook + 7;
   
        if (sz < sizeof(struct pppoe_full_hdr)) {        if ((size_t)sz < sizeof(struct pppoe_full_hdr)) {
                 Log(LG_PHYS, ("Incoming truncated PPPoE connection request via %s for "                  Log(LG_PHYS, ("Incoming truncated PPPoE connection request via %s for "
                     "service \"%s\"", PIf->ifnodepath, session));                      "service \"%s\"", PIf->ifnodepath, session));
                 return;                  return;
Line 947  PppoeListenEvent(int type, void *arg) Line 1284  PppoeListenEvent(int type, void *arg)
         wh = (struct pppoe_full_hdr *)response;          wh = (struct pppoe_full_hdr *)response;
         ph = &wh->ph;          ph = &wh->ph;
         if ((tag = get_tag(ph, PTT_SRV_NAME))) {          if ((tag = get_tag(ph, PTT_SRV_NAME))) {
            int len = ntohs(tag->tag_len);            size_t len = ntohs(tag->tag_len);
             if (len >= sizeof(real_session))              if (len >= sizeof(real_session))
                 len = sizeof(real_session)-1;                  len = sizeof(real_session)-1;
             memcpy(real_session, tag + 1, len);              memcpy(real_session, tag + 1, len);
Line 958  PppoeListenEvent(int type, void *arg) Line 1295  PppoeListenEvent(int type, void *arg)
         bzero(agent_cid, sizeof(agent_cid));          bzero(agent_cid, sizeof(agent_cid));
         bzero(agent_rid, sizeof(agent_rid));          bzero(agent_rid, sizeof(agent_rid));
         if ((tag = get_vs_tag(ph, htonl(0x00000DE9)))) {          if ((tag = get_vs_tag(ph, htonl(0x00000DE9)))) {
            int len = ntohs(tag->tag_len) - 4, pos = 0;            size_t len = ntohs(tag->tag_len) - 4, pos = 0;
             const char *b = (const char *)(tag + 1) + 4;              const char *b = (const char *)(tag + 1) + 4;
             while (pos + 1 <= len) {              while (pos + 1 <= len) {
                int len1 = b[pos + 1];                size_t len1 = b[pos + 1];
                 if (len1 > len - pos - 2)                  if (len1 > len - pos - 2)
                     break;                      break;
                 if (len1 >= sizeof(agent_rid))                  if (len1 >= sizeof(agent_rid))
Line 977  PppoeListenEvent(int type, void *arg) Line 1314  PppoeListenEvent(int type, void *arg)
                 pos += 2 + len1;                  pos += 2 + len1;
             }              }
         }          }
   
         Log(LG_PHYS, ("Incoming PPPoE connection request via %s for "          Log(LG_PHYS, ("Incoming PPPoE connection request via %s for "
             "service \"%s\" from %s", PIf->ifnodepath, real_session,              "service \"%s\" from %s", PIf->ifnodepath, real_session,
            ether_ntoa((struct  ether_addr *)&wh->eh.ether_shost)));            ether_ntoa((const struct ether_addr *)&wh->eh.ether_shost)));
   
           if (gLogOptions & LG_PHYS3)
               print_tags(ph);
   
         if (gShutdownInProgress) {          if (gShutdownInProgress) {
                 Log(LG_PHYS, ("Shutdown sequence in progress, ignoring request."));                  Log(LG_PHYS, ("Shutdown sequence in progress, ignoring request."));
                 return;                  return;
Line 1168  PppoeGetNode(Link l) Line 1509  PppoeGetNode(Link l)
                     l->name));                      l->name));
                 return;                  return;
         }          }
        if (CreatePppoeNode(&PppoeIfs[free], pi->path, pi->hook)) {        if (CreatePppoeNode(&PppoeIfs[free], pi->iface, pi->path, pi->hook)) {
                 strlcpy(PppoeIfs[free].ifnodepath,                  strlcpy(PppoeIfs[free].ifnodepath,
                     pi->path,                      pi->path,
                     sizeof(PppoeIfs[free].ifnodepath));                      sizeof(PppoeIfs[free].ifnodepath));
Line 1255  PppoeListen(Link l) Line 1596  PppoeListen(Link l)
   
         if (NgSendMsg(PIf->csock, ".:", NGM_GENERIC_COOKIE, NGM_CONNECT, &cn,          if (NgSendMsg(PIf->csock, ".:", NGM_GENERIC_COOKIE, NGM_CONNECT, &cn,
             sizeof(cn)) < 0) {              sizeof(cn)) < 0) {
                Log(LG_ERR, ("PPPoE: Can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\": %s",                Perror("PPPoE: Can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
                    ".:", cn.ourhook, cn.path, cn.peerhook,                    ".:", cn.ourhook, cn.path, cn.peerhook);
                    strerror(errno))); 
                 return(0);                  return(0);
         }          }
   
Line 1337  PppoeNodeUpdate(Link l) Line 1677  PppoeNodeUpdate(Link l)
  */   */
     
 static int  static int
PppoeSetCommand(Context ctx, int ac, char *av[], void *arg)PppoeSetCommand(Context ctx, int ac, const char *const av[], const void *arg)
 {  {
         const PppoeInfo pi = (PppoeInfo) ctx->lnk->info;          const PppoeInfo pi = (PppoeInfo) ctx->lnk->info;
         const char *hookname = ETHER_DEFAULT_HOOK;          const char *hookname = ETHER_DEFAULT_HOOK;
        const char *colon;        int i;
#ifdef NGM_PPPOE_SETMAXP_COOKIE
         int ap;
 #endif
         switch ((intptr_t)arg) {          switch ((intptr_t)arg) {
         case SET_IFACE:          case SET_IFACE:
                 switch (ac) {                  switch (ac) {
Line 1350  PppoeSetCommand(Context ctx, int ac, char *av[], void  Line 1692  PppoeSetCommand(Context ctx, int ac, char *av[], void 
                         hookname = av[1];                          hookname = av[1];
                         /* fall through */                          /* fall through */
                 case 1:                  case 1:
                        colon = (av[0][strlen(av[0]) - 1] == ':') ? "" : ":";                        strlcpy(pi->iface, av[0], sizeof(pi->iface));
                        snprintf(pi->path, sizeof(pi->path),                        strlcpy(pi->path, pi->iface, sizeof(pi->path) - 1);
                            "%s%s", av[0], colon);                        for (i = 0; i < sizeof(pi->path) - 1; i++) {
                                 if (pi->path[i] == '.' || pi->path[i] == ':')
                                         pi->path[i] = '_';
                                 else if (pi->path[i] == '\0') {
                                         pi->path[i] = ':';
                                         pi->path[i + 1] = '\0';
                                         break;
                                 }
                         }
                         strlcpy(pi->hook, hookname, sizeof(pi->hook));                          strlcpy(pi->hook, hookname, sizeof(pi->hook));
                         break;                          break;
                 default:                  default:
Line 1378  PppoeSetCommand(Context ctx, int ac, char *av[], void  Line 1728  PppoeSetCommand(Context ctx, int ac, char *av[], void 
                 if (ac != 1)                  if (ac != 1)
                         return(-1);                          return(-1);
                 strlcpy(pi->acname, av[0], sizeof(pi->acname));                  strlcpy(pi->acname, av[0], sizeof(pi->acname));
                   break;
   #ifdef NGM_PPPOE_SETMAXP_COOKIE
           case SET_MAX_PAYLOAD:
                   if (ac != 1)
                           return(-1);
                   ap = atoi(av[0]);
                   if (ap < PPPOE_MRU || ap > ETHER_MAX_LEN - 8)
                           Error("PPP-Max-Payload value \"%s\"", av[0]);
                   pi->max_payload = ap;
                   break;
   #endif
           case SET_MAC_FORMAT:
                   if (ac != 1)
                           return(-1);
                   if (strcmp(av[0], "unformatted") == 0) {
                       pi->mac_format = MAC_UNFORMATTED;
                   } else if (strcmp(av[0], "unix-like") == 0) {
                       pi->mac_format = MAC_UNIX_LIKE;
                   } else if (strcmp(av[0], "cisco-like") == 0) {
                       pi->mac_format = MAC_CISCO_LIKE;
                   } else if (strcmp(av[0], "ietf") == 0) {
                       pi->mac_format = MAC_IETF;
                   } else {
                       Error("Incorrect PPPoE mac-format \"%s\"", av[0]);
                   }
                 break;                  break;
         default:          default:
                 assert(0);                  assert(0);

Removed from v.1.1  
changed lines
  Added in v.1.1.1.5


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