| 26 |
26 |
/*
|
| 27 |
27 |
* DEFINITIONS
|
| 28 |
28 |
*/
|
| 29 |
|
|
| 30 |
29 |
#define PPPOE_MTU 1492 /* allow room for PPPoE overhead */
|
| 31 |
30 |
#define PPPOE_MRU 1492
|
| 32 |
31 |
|
| ... | ... | |
| 74 |
73 |
char hook[NG_HOOKSIZ]; /* hook on that node */
|
| 75 |
74 |
char session[MAX_SESSION]; /* session name */
|
| 76 |
75 |
char acname[PPPOE_SERVICE_NAME_SIZE]; /* AC name */
|
|
76 |
uint16_t max_payload; /* PPP-Max-Payload (RFC4638) */
|
| 77 |
77 |
int mac_format; /* MAC address format */
|
| 78 |
78 |
u_char peeraddr[6]; /* Peer MAC address */
|
| 79 |
79 |
char real_session[MAX_SESSION]; /* real session name */
|
| ... | ... | |
| 81 |
81 |
char agent_rid[64]; /* Agent Remote ID */
|
| 82 |
82 |
u_char incoming; /* incoming vs. outgoing */
|
| 83 |
83 |
u_char opened; /* PPPoE opened by phys */
|
|
84 |
u_char mp_reply; /* PPP-Max-Payload reply from server */
|
| 84 |
85 |
struct optinfo options;
|
| 85 |
86 |
struct PppoeIf *PIf; /* pointer on parent ng_pppoe info */
|
| 86 |
87 |
struct PppoeList *list;
|
| ... | ... | |
| 95 |
96 |
SET_IFACE,
|
| 96 |
97 |
SET_SESSION,
|
| 97 |
98 |
SET_ACNAME,
|
|
99 |
SET_MAX_PAYLOAD,
|
| 98 |
100 |
SET_MAC_FORMAT
|
| 99 |
101 |
};
|
| 100 |
102 |
|
| ... | ... | |
| 147 |
149 |
static int PppoeCalledNum(Link l, void *buf, size_t buf_len);
|
| 148 |
150 |
static int PppoeSelfName(Link l, void *buf, size_t buf_len);
|
| 149 |
151 |
static int PppoePeerName(Link l, void *buf, size_t buf_len);
|
|
152 |
static u_short PppoeGetMru(Link l, int conf);
|
| 150 |
153 |
static void PppoeCtrlReadEvent(int type, void *arg);
|
| 151 |
154 |
static void PppoeConnectTimeout(void *arg);
|
| 152 |
155 |
static void PppoeStat(Context ctx);
|
| ... | ... | |
| 189 |
192 |
.callednum = PppoeCalledNum,
|
| 190 |
193 |
.selfname = PppoeSelfName,
|
| 191 |
194 |
.peername = PppoePeerName,
|
|
195 |
.getmru = PppoeGetMru
|
| 192 |
196 |
};
|
| 193 |
197 |
|
| 194 |
198 |
const struct cmdtab PppoeSetCmds[] = {
|
| ... | ... | |
| 198 |
202 |
PppoeSetCommand, NULL, 2, (void *)SET_SESSION },
|
| 199 |
203 |
{ "acname {name}", "Set PPPoE access concentrator name",
|
| 200 |
204 |
PppoeSetCommand, NULL, 2, (void *)SET_ACNAME },
|
| 201 |
|
{ "mac-format {format}", "set radius attribute 31 mac format",
|
|
205 |
#ifdef NGM_PPPOE_SETMAXP_COOKIE
|
|
206 |
{ "max-payload {size}", "Set PPP-Max-Payload tag",
|
|
207 |
PppoeSetCommand, NULL, 2, (void *)SET_MAX_PAYLOAD },
|
|
208 |
#endif
|
|
209 |
{ "mac-format {format}", "Set RADIUS attribute 31 MAC format",
|
| 202 |
210 |
PppoeSetCommand, NULL, 2, (void *)SET_MAC_FORMAT },
|
| 203 |
211 |
{ NULL }
|
| 204 |
212 |
};
|
| ... | ... | |
| 239 |
247 |
{ PTT_HOST_UNIQ, "Host-Uniq" },
|
| 240 |
248 |
{ PTT_AC_COOKIE, "AC-Cookie" },
|
| 241 |
249 |
{ PTT_VENDOR, "Vendor-Specific" },
|
| 242 |
|
{ PTT_RELAY_SID, "Relay-Session-ID" },
|
|
250 |
{ PTT_RELAY_SID, "Relay-Session-Id" },
|
| 243 |
251 |
{ PTT_MAX_PAYL, "PPP-Max-Payload" },
|
| 244 |
252 |
{ PTT_SRV_ERR, "Service-Name-Error" },
|
| 245 |
253 |
{ PTT_SYS_ERR, "AC-System-Error" },
|
| 246 |
254 |
{ PTT_GEN_ERR, "Generic-Error" },
|
| 247 |
|
/* http://tools.ietf.org/html/draft-arberg-pppoe-iana-00 */
|
|
255 |
/* RFC 4937 */
|
| 248 |
256 |
{ MPD_PTT_CREDITS, "Credits" },
|
| 249 |
257 |
{ MPD_PTT_METRICS, "Metrics" },
|
| 250 |
258 |
{ MPD_PTT_SEQ_NUMBER, "Sequence Number" },
|
| ... | ... | |
| 278 |
286 |
pe->agent_cid[0] = 0;
|
| 279 |
287 |
pe->agent_rid[0] = 0;
|
| 280 |
288 |
pe->PIf = NULL;
|
|
289 |
pe->max_payload = 0;
|
| 281 |
290 |
pe->mac_format = MAC_UNFORMATTED;
|
|
291 |
pe->mp_reply = 0;
|
| 282 |
292 |
|
| 283 |
293 |
/* Done */
|
| 284 |
294 |
return(0);
|
| ... | ... | |
| 393 |
403 |
l->name, path, cn.ourhook, cn.path, cn.peerhook);
|
| 394 |
404 |
goto fail2;
|
| 395 |
405 |
}
|
| 396 |
|
|
|
406 |
|
|
407 |
#ifdef NGM_PPPOE_SETMAXP_COOKIE
|
|
408 |
if (pe->max_payload > 0) {
|
|
409 |
const uint16_t max_payload = pe->max_payload;
|
|
410 |
Log(LG_PHYS, ("[%s] PPPoE: Set PPP-Max-Payload to '%d'",
|
|
411 |
l->name, max_payload));
|
|
412 |
/* Tell the PPPoE node to set PPP-Max-Payload value. */
|
|
413 |
if (NgSendMsg(pe->PIf->csock, path, NGM_PPPOE_COOKIE, NGM_PPPOE_SETMAXP,
|
|
414 |
&max_payload, sizeof(uint16_t)) < 0) {
|
|
415 |
Perror("[%s] PPPoE can't set PPP-Max-Payload value", l->name);
|
|
416 |
goto fail2;
|
|
417 |
}
|
|
418 |
}
|
|
419 |
#endif
|
|
420 |
|
| 397 |
421 |
Log(LG_PHYS, ("[%s] PPPoE: Connecting to '%s'", l->name, pe->session));
|
| 398 |
422 |
|
| 399 |
423 |
/* Tell the PPPoE node to try to connect to a server. */
|
| ... | ... | |
| 417 |
441 |
strlcpy(pe->real_session, pe->session, sizeof(pe->real_session));
|
| 418 |
442 |
pe->agent_cid[0] = 0;
|
| 419 |
443 |
pe->agent_rid[0] = 0;
|
|
444 |
pe->mp_reply = 0;
|
| 420 |
445 |
return;
|
| 421 |
446 |
|
| 422 |
447 |
fail3:
|
| ... | ... | |
| 499 |
524 |
pi->real_session[0] = 0;
|
| 500 |
525 |
pi->agent_cid[0] = 0;
|
| 501 |
526 |
pi->agent_rid[0] = 0;
|
|
527 |
pi->mp_reply = 0;
|
| 502 |
528 |
}
|
| 503 |
529 |
|
| 504 |
530 |
/*
|
| ... | ... | |
| 510 |
536 |
PppoeCtrlReadEvent(int type, void *arg)
|
| 511 |
537 |
{
|
| 512 |
538 |
union {
|
|
539 |
#ifdef NGM_PPPOE_SETMAXP_COOKIE
|
|
540 |
u_char buf[sizeof(struct ng_mesg) + sizeof(struct ngpppoe_maxp)];
|
|
541 |
#else
|
| 513 |
542 |
u_char buf[sizeof(struct ng_mesg) + sizeof(struct ngpppoe_sts)];
|
|
543 |
#endif
|
| 514 |
544 |
struct ng_mesg resp;
|
| 515 |
545 |
} u;
|
| 516 |
546 |
char path[NG_PATHSIZ];
|
| ... | ... | |
| 534 |
564 |
case NGM_PPPOE_SUCCESS:
|
| 535 |
565 |
case NGM_PPPOE_FAIL:
|
| 536 |
566 |
case NGM_PPPOE_CLOSE:
|
|
567 |
#ifdef NGM_PPPOE_SETMAXP_COOKIE
|
|
568 |
case NGM_PPPOE_SETMAXP:
|
|
569 |
#endif
|
| 537 |
570 |
{
|
| 538 |
571 |
char ppphook[NG_HOOKSIZ];
|
| 539 |
572 |
char *linkname, *rest;
|
| ... | ... | |
| 576 |
609 |
/* Decode message. */
|
| 577 |
610 |
switch (u.resp.header.cmd) {
|
| 578 |
611 |
case NGM_PPPOE_SESSIONID: /* XXX: I do not know what to do with this? */
|
|
612 |
Log(LG_PHYS3, ("PPPoE: rec'd SESSIONID %u from \"%s\"",
|
|
613 |
ntohs((uint16_t)u.resp.data), path));
|
| 579 |
614 |
break;
|
| 580 |
615 |
case NGM_PPPOE_SUCCESS:
|
| 581 |
616 |
Log(LG_PHYS, ("[%s] PPPoE: connection successful", l->name));
|
| ... | ... | |
| 601 |
636 |
Log(LG_PHYS, ("PPPoE: rec'd ACNAME \"%s\"",
|
| 602 |
637 |
((struct ngpppoe_sts *)u.resp.data)->hook));
|
| 603 |
638 |
break;
|
|
639 |
#ifdef NGM_PPPOE_SETMAXP_COOKIE
|
|
640 |
case NGM_PPPOE_SETMAXP:
|
|
641 |
{
|
|
642 |
struct ngpppoe_maxp *maxp;
|
|
643 |
|
|
644 |
maxp = ((struct ngpppoe_maxp *)u.resp.data);
|
|
645 |
Log(LG_PHYS, ("[%s] PPPoE: rec'd PPP-Max-Payload '%u'",
|
|
646 |
l->name, maxp->data));
|
|
647 |
if (pi->max_payload > 0) {
|
|
648 |
if (pi->max_payload == maxp->data)
|
|
649 |
pi->mp_reply = 1;
|
|
650 |
else
|
|
651 |
Log(LG_PHYS,
|
|
652 |
("[%s] PPPoE: sent and returned values are not equal",
|
|
653 |
l->name));
|
|
654 |
} else
|
|
655 |
Log(LG_PHYS, ("[%s] PPPoE: server sent tag PPP-Max-Payload"
|
|
656 |
" without request from the client",
|
|
657 |
l->name));
|
|
658 |
break;
|
|
659 |
}
|
|
660 |
#endif
|
| 604 |
661 |
default:
|
| 605 |
662 |
Log(LG_PHYS, ("PPPoE: rec'd command %lu from \"%s\"",
|
| 606 |
663 |
(u_long)u.resp.header.cmd, path));
|
| ... | ... | |
| 639 |
696 |
Printf("\tIface Node : %s\r\n", pe->path);
|
| 640 |
697 |
Printf("\tIface Hook : %s\r\n", pe->hook);
|
| 641 |
698 |
Printf("\tSession : %s\r\n", pe->session);
|
|
699 |
#ifdef NGM_PPPOE_SETMAXP_COOKIE
|
|
700 |
Printf("\tMax-Payload : %d\r\n", pe->max_payload);
|
|
701 |
#endif
|
| 642 |
702 |
Printf("\tMAC format : %s\r\n", buf);
|
| 643 |
703 |
Printf("PPPoE status:\r\n");
|
| 644 |
704 |
if (ctx->lnk->state != PHYS_STATE_DOWN) {
|
| ... | ... | |
| 647 |
707 |
PppoePeerMacAddr(ctx->lnk, buf, sizeof(buf));
|
| 648 |
708 |
Printf("\tCurrent peer : %s\r\n", buf);
|
| 649 |
709 |
Printf("\tSession : %s\r\n", pe->real_session);
|
|
710 |
Printf("\tMax-Payload : %s\r\n", (pe->mp_reply?"YES":"NO"));
|
| 650 |
711 |
Printf("\tCircuit-ID : %s\r\n", pe->agent_cid);
|
| 651 |
712 |
Printf("\tRemote-ID : %s\r\n", pe->agent_rid);
|
| 652 |
713 |
}
|
| ... | ... | |
| 788 |
849 |
return (0);
|
| 789 |
850 |
}
|
| 790 |
851 |
|
|
852 |
static u_short
|
|
853 |
PppoeGetMru(Link l, int conf)
|
|
854 |
{
|
|
855 |
PppoeInfo const pppoe = (PppoeInfo)l->info;
|
|
856 |
|
|
857 |
if (pppoe->max_payload > 0 && pppoe->mp_reply > 0)
|
|
858 |
return (pppoe->max_payload);
|
|
859 |
else
|
|
860 |
if (conf == 0)
|
|
861 |
return (l->type->mru);
|
|
862 |
else
|
|
863 |
return (l->conf.mru);
|
|
864 |
}
|
|
865 |
|
| 791 |
866 |
static int
|
| 792 |
867 |
CreatePppoeNode(struct PppoeIf *PIf, const char *path, const char *hook)
|
| 793 |
868 |
{
|
| ... | ... | |
| 1122 |
1197 |
/* First check our stat list for known tags */
|
| 1123 |
1198 |
for (k = 0; k < NUM_TAG_NAMES; k++) {
|
| 1124 |
1199 |
if (pt->tag_type == tag2str[k].tag) {
|
| 1125 |
|
sprintf(tag, tag2str[k].name);
|
|
1200 |
sprintf(tag, "%s", tag2str[k].name);
|
| 1126 |
1201 |
break;
|
| 1127 |
1202 |
}
|
| 1128 |
1203 |
}
|
| ... | ... | |
| 1583 |
1658 |
const PppoeInfo pi = (PppoeInfo) ctx->lnk->info;
|
| 1584 |
1659 |
const char *hookname = ETHER_DEFAULT_HOOK;
|
| 1585 |
1660 |
const char *colon;
|
| 1586 |
|
|
|
1661 |
#ifdef NGM_PPPOE_SETMAXP_COOKIE
|
|
1662 |
int ap;
|
|
1663 |
#endif
|
| 1587 |
1664 |
switch ((intptr_t)arg) {
|
| 1588 |
1665 |
case SET_IFACE:
|
| 1589 |
1666 |
switch (ac) {
|
| ... | ... | |
| 1620 |
1697 |
return(-1);
|
| 1621 |
1698 |
strlcpy(pi->acname, av[0], sizeof(pi->acname));
|
| 1622 |
1699 |
break;
|
|
1700 |
#ifdef NGM_PPPOE_SETMAXP_COOKIE
|
|
1701 |
case SET_MAX_PAYLOAD:
|
|
1702 |
if (ac != 1)
|
|
1703 |
return(-1);
|
|
1704 |
ap = atoi(av[0]);
|
|
1705 |
if (ap < ETHER_MIN_LEN + 8 || ap > ETHER_MAX_LEN - 8)
|
|
1706 |
Error("PPP-Max-Payload value \"%s\"", av[0]);
|
|
1707 |
pi->max_payload = ap;
|
|
1708 |
break;
|
|
1709 |
#endif
|
| 1623 |
1710 |
case SET_MAC_FORMAT:
|
| 1624 |
1711 |
if (ac != 1)
|
| 1625 |
1712 |
return(-1);
|
| ... | ... | |
| 1632 |
1719 |
} else if (strcmp(av[0], "ietf") == 0) {
|
| 1633 |
1720 |
pi->mac_format = MAC_IETF;
|
| 1634 |
1721 |
} else {
|
| 1635 |
|
Error("Incorrect pppoe mac-format");
|
|
1722 |
Error("Incorrect PPPoE mac-format \"%s\"", av[0]);
|
| 1636 |
1723 |
}
|
| 1637 |
1724 |
break;
|
| 1638 |
1725 |
default:
|