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); |