Diff for /embedaddon/mpd/src/pppoe.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2012/02/21 23:32:47 version 1.1.1.4, 2019/10/22 13:49:55
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 <netgraph/ng_message.h>  #include <netgraph/ng_message.h>
 #include <netgraph/ng_pppoe.h>  #include <netgraph/ng_pppoe.h>
Line 34 Line 35
   
 #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 98  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 152  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);
Line 120  static int  PppoeListen(Link l); Line 166  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 196  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 207  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 }
 };  };
   
 /*   /* 
Line 186  struct PppoeIf { Line 240  struct PppoeIf {
 int PppoeIfCount=0;  int PppoeIfCount=0;
 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 463  PppoeCtrlReadEvent(int type, void *arg) Line 568  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 613  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 640  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 *)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 688  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 722  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 587  PppoePeerMacAddr(Link l, void *buf, size_t buf_len) Line 753  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",        ether_ntoa_r((struct ether_addr *)pppoe->peeraddr, buf);
            pppoe->peeraddr[0], pppoe->peeraddr[1], pppoe->peeraddr[2],  
            pppoe->peeraddr[3], pppoe->peeraddr[4], pppoe->peeraddr[5]); 
 
         return (0);          return (0);
 }  }
   
Line 598  static int Line 761  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 772  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 809  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 860  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 898  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 (ExecCmdNosh(LG_PHYS2, iface, "%s %s up", _PATH_IFCONFIG, iface) != 0) {
 
        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",                  Log(LG_ERR, ("PPPoE: can't bring up interface %s",
                     iface));                      iface));
                 return (0);                  return (0);
Line 894  get_vs_tag(const struct pppoe_hdr* ph, uint32_t idx) Line 1118  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 ((uint8_t)*(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", *(uint16_t*)(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 977  PppoeListenEvent(int type, void *arg) Line 1310  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((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 1505  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 1592  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 1341  PppoeSetCommand(Context ctx, int ac, char *av[], void  Line 1677  PppoeSetCommand(Context ctx, int ac, char *av[], void 
 {  {
         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 1688  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 1724  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.1.1  
changed lines
  Added in v.1.1.1.4


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