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

version 1.1.1.4, 2019/10/22 13:49:55 version 1.1.1.5.2.1, 2023/09/27 11:08:01
Line 15 Line 15
   
 #include <paths.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 28 Line 29
  * DEFINITIONS   * DEFINITIONS
  */   */
   
   #define PPPOE_MTU_MAX           (ETHER_MAX_LEN_JUMBO - 8)
 #define PPPOE_MTU               1492    /* allow room for PPPoE overhead */  #define PPPOE_MTU               1492    /* allow room for PPPoE overhead */
 #define PPPOE_MRU               1492  #define PPPOE_MRU               1492
   
Line 157  static u_short PppoeGetMru(Link l, int conf); Line 159  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 177  static void PppoeDoClose(Link l); Line 179  static void PppoeDoClose(Link l);
 const struct phystype gPppoePhysType = {  const struct phystype gPppoePhysType = {
     .name               = "pppoe",      .name               = "pppoe",
     .descr              = "PPP over Ethernet",      .descr              = "PPP over Ethernet",
    .mtu                = PPPOE_MTU,    .mtu                = PPPOE_MTU_MAX,
     .mru                = PPPOE_MRU,      .mru                = PPPOE_MRU,
     .tmpl               = 1,      .tmpl               = 1,
     .init               = PppoeInit,      .init               = PppoeInit,
Line 213  const struct cmdtab PppoeSetCmds[] = { Line 215  const struct cmdtab PppoeSetCmds[] = {
 #endif  #endif
       { "mac-format {format}",  "Set RADIUS attribute 31 MAC format",        { "mac-format {format}",  "Set RADIUS attribute 31 MAC format",
           PppoeSetCommand, NULL, 2, (void *)SET_MAC_FORMAT },            PppoeSetCommand, NULL, 2, (void *)SET_MAC_FORMAT },
      { NULL }      { NULL, NULL, NULL, NULL, 0, NULL }
 };  };
   
 /*   /* 
Line 237  struct PppoeIf { Line 239  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 {  struct tagname {
     int         tag;      int         tag;
Line 407  PppoeOpen(Link l) Line 408  PppoeOpen(Link l)
             &cn, sizeof(cn)) < 0) {              &cn, sizeof(cn)) < 0) {
                 Perror("[%s] PPPoE: can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",                  Perror("[%s] PPPoE: can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
                     l->name, path, cn.ourhook, cn.path, cn.peerhook);                      l->name, path, cn.ourhook, cn.path, cn.peerhook);
                   if (errno == ENOENT) {
                       PppoeReleaseNode(l);
                       goto fail;
                   }
                 goto fail2;                  goto fail2;
         }          }
                   
Line 552  PppoeCtrlReadEvent(int type, void *arg) Line 557  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 614  PppoeCtrlReadEvent(int type, void *arg) Line 620  PppoeCtrlReadEvent(int type, void *arg)
         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\"",                  Log(LG_PHYS3, ("PPPoE: rec'd SESSIONID %u from \"%s\"",
                  ntohs((uint16_t)u.resp.data), path));                  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 645  PppoeCtrlReadEvent(int type, void *arg) Line 651  PppoeCtrlReadEvent(int type, void *arg)
             {              {
                 struct ngpppoe_maxp *maxp;                  struct ngpppoe_maxp *maxp;
                                   
                maxp = ((struct ngpppoe_maxp *)u.resp.data);                maxp = ((struct ngpppoe_maxp *)(void *)u.resp.data);
                 Log(LG_PHYS, ("[%s] PPPoE: rec'd PPP-Max-Payload '%u'",                  Log(LG_PHYS, ("[%s] PPPoE: rec'd PPP-Max-Payload '%u'",
                   l->name, maxp->data));                    l->name, maxp->data));
                 if (pi->max_payload > 0) {                  if (pi->max_payload > 0) {
Line 745  PppoeOriginated(Link l) Line 751  PppoeOriginated(Link l)
 static int  static int
 PppoeIsSync(Link l)  PppoeIsSync(Link l)
 {  {
           (void)l;
         return (1);          return (1);
 }  }
   
Line 753  PppoePeerMacAddr(Link l, void *buf, size_t buf_len) Line 760  PppoePeerMacAddr(Link l, void *buf, size_t buf_len)
 {  {
         PppoeInfo       const pppoe = (PppoeInfo)l->info;          PppoeInfo       const pppoe = (PppoeInfo)l->info;
   
           if (buf_len < 18)
                   return (1);
         ether_ntoa_r((struct ether_addr *)pppoe->peeraddr, buf);          ether_ntoa_r((struct ether_addr *)pppoe->peeraddr, buf);
         return (0);          return (0);
 }  }
Line 871  PppoeGetMtu(Link l, int conf) Line 880  PppoeGetMtu(Link l, int conf)
             if (conf == 0)              if (conf == 0)
                 return (l->type->mtu);                  return (l->type->mtu);
             else              else
                return (l->conf.mtu);                return (l->conf.mtu ? l->conf.mtu : PPPOE_MTU);
 }  }
   
 static u_short  static u_short
Line 901  CreatePppoeNode(struct PppoeIf *PIf, const char *iface Line 910  CreatePppoeNode(struct PppoeIf *PIf, const char *iface
         uint32_t f;          uint32_t f;
   
         /* Make sure interface is up. */          /* Make sure interface is up. */
        if (ExecCmdNosh(LG_PHYS2, iface, "%s %s up", _PATH_IFCONFIG, iface) != 0) {        if (IfaceSetFlag(iface, IFF_UP) != 0) {
                Log(LG_ERR, ("PPPoE: can't bring up interface %s",                Perror("[%s] PPPoE: can't bring up interface", iface);
                    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 940  CreatePppoeNode(struct PppoeIf *PIf, const char *iface Line 947  CreatePppoeNode(struct PppoeIf *PIf, const char *iface
                 }                  }
   
                 /* 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 979  CreatePppoeNode(struct PppoeIf *PIf, const char *iface Line 986  CreatePppoeNode(struct PppoeIf *PIf, const char *iface
                 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 1040  CreatePppoeNode(struct PppoeIf *PIf, const char *iface Line 1047  CreatePppoeNode(struct PppoeIf *PIf, const char *iface
                 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 1108  get_vs_tag(const struct pppoe_hdr* ph, uint32_t idx) Line 1116  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 1167  print_tags(const struct pppoe_hdr* ph) Line 1175  print_tags(const struct pppoe_hdr* ph)
                         break;                          break;
                     case PTT_VENDOR:                      case PTT_VENDOR:
                         if (len >= 4) {                          if (len >= 4) {
                            if ((uint8_t)*(uint8_t*)v != 0) {                            if ((const uint8_t)*(const uint8_t*)v != 0) {
                                 snprintf(buf, sizeof(buf),                                  snprintf(buf, sizeof(buf),
                                     "First byte of VENDOR is not zero! 0x%s",                                      "First byte of VENDOR is not zero! 0x%s",
                                     Bin2Hex(v, len));                                      Bin2Hex(v, len));
Line 1184  print_tags(const struct pppoe_hdr* ph) Line 1192  print_tags(const struct pppoe_hdr* ph)
                         if (len != 2) {                          if (len != 2) {
                             sprintf(buf, "TAG_LENGTH is not 2!");                              sprintf(buf, "TAG_LENGTH is not 2!");
                         } else {                          } else {
                            sprintf(buf, "%u", *(uint16_t*)(pt + 1));                            sprintf(buf, "%u", *(const uint16_t*)(const void *)(pt + 1));
                         }                          }
                         break;                          break;
                     case PTT_SRV_ERR:                      case PTT_SRV_ERR:
Line 1249  PppoeListenEvent(int type, void *arg) Line 1257  PppoeListenEvent(int type, void *arg)
         const struct pppoe_hdr  *ph;          const struct pppoe_hdr  *ph;
         const struct pppoe_tag  *tag;          const struct pppoe_tag  *tag;
   
           u_int16_t               length;
   
         union {          union {
             u_char buf[sizeof(struct ngpppoe_init_data) + MAX_SESSION];              u_char buf[sizeof(struct ngpppoe_init_data) + MAX_SESSION];
             struct ngpppoe_init_data poeid;              struct ngpppoe_init_data poeid;
         } 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 1271  PppoeListenEvent(int type, void *arg) Line 1282  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 1279  PppoeListenEvent(int type, void *arg) Line 1290  PppoeListenEvent(int type, void *arg)
   
         wh = (struct pppoe_full_hdr *)response;          wh = (struct pppoe_full_hdr *)response;
         ph = &wh->ph;          ph = &wh->ph;
   
           /* Sanity check */
           length = ntohs(ph->length);
           if (length > (size_t)sz - sizeof(struct pppoe_full_hdr)) {
                   Log(LG_PHYS, ("Ignored incoming PPPoE connection request "
                       "via %s for service \"%s\" from %s "
                       "due to bad length %hu > %u",
                       PIf->ifnodepath, session,
                       ether_ntoa((const struct ether_addr *)&wh->eh.ether_shost),
                       length,
                       (unsigned)((size_t)sz - sizeof(struct pppoe_full_hdr))));
                   return;
           }
   
         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 1291  PppoeListenEvent(int type, void *arg) Line 1316  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 1313  PppoeListenEvent(int type, void *arg) Line 1338  PppoeListenEvent(int type, void *arg)
   
         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)          if (gLogOptions & LG_PHYS3)
             print_tags(ph);              print_tags(ph);
Line 1673  PppoeNodeUpdate(Link l) Line 1698  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;
         int i;          int i;
 #ifdef NGM_PPPOE_SETMAXP_COOKIE  #ifdef NGM_PPPOE_SETMAXP_COOKIE
         int ap;          int ap;
           uint16_t mtu;
 #endif  #endif
         switch ((intptr_t)arg) {          switch ((intptr_t)arg) {
         case SET_IFACE:          case SET_IFACE:
Line 1700  PppoeSetCommand(Context ctx, int ac, char *av[], void  Line 1726  PppoeSetCommand(Context ctx, int ac, char *av[], void 
                                 }                                  }
                         }                          }
                         strlcpy(pi->hook, hookname, sizeof(pi->hook));                          strlcpy(pi->hook, hookname, sizeof(pi->hook));
   
   #ifdef NGM_PPPOE_SETMAXP_COOKIE
                           if (pi->max_payload > 0) {
                                   mtu = GetSystemIfaceMTU(pi->iface);
                                   if (mtu == 0)
                                           mtu = ETHER_MAX_LEN;
                                   if (pi->max_payload > mtu - 8) {
                                           pi->max_payload = mtu - 8;
                                           Perror("[%s] PPPoE: PPP-Max-Payload"
                                                  " value reduced to %hu",
                                                   pi->iface, pi->max_payload);
                                   }
                           }
   #endif
                         break;                          break;
                 default:                  default:
                         return(-1);                          return(-1);
Line 1730  PppoeSetCommand(Context ctx, int ac, char *av[], void  Line 1770  PppoeSetCommand(Context ctx, int ac, char *av[], void 
                 if (ac != 1)                  if (ac != 1)
                         return(-1);                          return(-1);
                 ap = atoi(av[0]);                  ap = atoi(av[0]);
                if (ap < PPPOE_MRU || ap > ETHER_MAX_LEN - 8)                if (pi->iface[0] == '\0') {
                        Error("PPP-Max-Payload value \"%s\"", av[0]);                        if (ap < PPPOE_MRU)     /* postpone check for MTU */
                             Error("PPP-Max-Payload value \"%s\" less than %d",
                                 av[0], PPPOE_MRU);
                 } else {
                         mtu = GetSystemIfaceMTU(pi->iface);
                         if (mtu == 0)
                                 mtu = ETHER_MAX_LEN;
                         if (ap < PPPOE_MRU || ap > mtu - 8)
                             Error("PPP-Max-Payload value \"%s\" not in a range of %d..%hu",
                                 av[0], PPPOE_MRU, mtu);
                 }
                 pi->max_payload = ap;                  pi->max_payload = ap;
                 break;                  break;
 #endif  #endif

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5.2.1


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