|
version 1.1.1.2, 2013/07/22 08:44:29
|
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 36
|
Line 38
|
| #define ETHER_DEFAULT_HOOK NG_ETHER_HOOK_ORPHAN |
#define ETHER_DEFAULT_HOOK NG_ETHER_HOOK_ORPHAN |
| |
|
| #ifndef SMALL_SYSTEM |
#ifndef SMALL_SYSTEM |
| #define PPPOE_MAXPARENTIFS 1024 | #define PPPOE_MAXPARENTIFS 4096 |
| #else |
#else |
| #define PPPOE_MAXPARENTIFS 32 |
#define PPPOE_MAXPARENTIFS 32 |
| #endif |
#endif |
|
Line 44
|
Line 46
|
| #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 69 static u_char gNgEtherLoaded = FALSE;
|
Line 100 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 113 static int PppoeCallingNum(Link l, void *buf, size_t b
|
Line 154 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 125 static int PppoeListen(Link l);
|
Line 168 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 136 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 155 const struct phystype gPppoePhysType = {
|
Line 198 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 164 const struct cmdtab PppoeSetCmds[] = {
|
Line 209 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 188 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 { |
| |
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 205 PppoeInit(Link l)
|
Line 284 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 213 PppoeInit(Link l)
|
Line 293 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 325 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; |
| } |
} |
| |
|
| |
#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 351 PppoeOpen(Link l)
|
Line 450 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 433 PppoeDoClose(Link l)
|
Line 533 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 444 static void
|
Line 545 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 452 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 468 PppoeCtrlReadEvent(int type, void *arg)
|
Line 574 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 510 PppoeCtrlReadEvent(int type, void *arg)
|
Line 619 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 535 PppoeCtrlReadEvent(int type, void *arg)
|
Line 646 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 551 PppoeStat(Context ctx)
|
Line 694 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 562 PppoeStat(Context ctx)
|
Line 728 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 584 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 592 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 600 static int
|
Line 770 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 615 PppoeCallingNum(Link l, void *buf, size_t buf_len)
|
Line 781 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) { |
| ether_ntoa_r((struct ether_addr *)pppoe->peeraddr, buf); | switch (pppoe->mac_format) { |
| | case MAC_UNFORMATTED: |
| | 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 818 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) { |
| ether_ntoa_r((struct ether_addr *)pppoe->peeraddr, buf); | switch (pppoe->mac_format) { |
| | case MAC_UNFORMATTED: |
| | 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 657 PppoePeerName(Link l, void *buf, size_t buf_len)
|
Line 869 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 ? l->conf.mtu : PPPOE_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 667 CreatePppoeNode(struct PppoeIf *PIf, const char *path,
|
Line 907 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 714 CreatePppoeNode(struct PppoeIf *PIf, const char *path,
|
Line 947 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 753 CreatePppoeNode(struct PppoeIf *PIf, const char *path,
|
Line 986 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 814 CreatePppoeNode(struct PppoeIf *PIf, const char *path,
|
Line 1047 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 882 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 892 get_vs_tag(const struct pppoe_hdr* ph, uint32_t idx)
|
Line 1126 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 914 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 936 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 944 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 956 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 975 PppoeListenEvent(int type, void *arg)
|
Line 1335 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 1166 PppoeGetNode(Link l)
|
Line 1530 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 1253 PppoeListen(Link l)
|
Line 1617 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 1335 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; |
| const char *colon; | int i; |
| #ifdef NGM_PPPOE_SETMAXP_COOKIE |
| | int ap; |
| | uint16_t mtu; |
| | #endif |
| switch ((intptr_t)arg) { |
switch ((intptr_t)arg) { |
| case SET_IFACE: |
case SET_IFACE: |
| switch (ac) { |
switch (ac) { |
|
Line 1348 PppoeSetCommand(Context ctx, int ac, char *av[], void
|
Line 1714 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)); |
| |
|
| |
#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 1376 PppoeSetCommand(Context ctx, int ac, char *av[], void
|
Line 1764 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 (pi->iface[0] == '\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; |
| |
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); |