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:
|