version 1.1.1.3, 2016/11/01 09:56:12
|
version 1.1.1.5, 2021/03/17 00:39:23
|
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 71
|
Line 72
|
|
|
/* 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 */ |
Line 156 static u_short PppoeGetMru(Link l, int conf);
|
Line 158 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 165 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 212 const struct cmdtab PppoeSetCmds[] = {
|
Line 214 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 236 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 { |
struct tagname { |
int tag; |
int tag; |
Line 282 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 550 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 643 PppoeCtrlReadEvent(int type, void *arg)
|
Line 646 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 660 PppoeCtrlReadEvent(int type, void *arg)
|
Line 663 PppoeCtrlReadEvent(int type, void *arg)
|
break; |
break; |
} |
} |
#endif |
#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 695 PppoeStat(Context ctx)
|
Line 708 PppoeStat(Context ctx)
|
} |
} |
|
|
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); |
Line 732 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 740 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; |
|
|
|
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 748 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 880 PppoeGetMru(Link l, int conf)
|
Line 893 PppoeGetMru(Link l, int conf)
|
} |
} |
|
|
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 892 CreatePppoeNode(struct PppoeIf *PIf, const char *path,
|
Line 905 CreatePppoeNode(struct PppoeIf *PIf, const char *path,
|
uint32_t 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 936 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 975 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 1036 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 1104 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 1163 print_tags(const struct pppoe_hdr* ph)
|
Line 1170 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 1180 print_tags(const struct pppoe_hdr* ph)
|
Line 1187 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 1251 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 1267 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 1276 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 1287 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 1309 PppoeListenEvent(int type, void *arg)
|
Line 1317 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 1501 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 1669 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 |
#ifdef NGM_PPPOE_SETMAXP_COOKIE |
int ap; |
int ap; |
#endif |
#endif |
Line 1684 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: |