Page MenuHomeFreeBSD

D9270.id24314.diff
No OneTemporary

D9270.id24314.diff

Index: share/man/man4/ng_pppoe.4
===================================================================
--- share/man/man4/ng_pppoe.4
+++ share/man/man4/ng_pppoe.4
@@ -35,7 +35,7 @@
.\" $FreeBSD$
.\" $Whistle: ng_pppoe.8,v 1.1 1999/01/25 23:46:27 archie Exp $
.\"
-.Dd September 15, 2015
+.Dd January 20, 2017
.Dt NG_PPPOE 4
.Os
.Sh NAME
@@ -104,12 +104,22 @@
It must be newly created and a service name can be given as an argument.
It is legal to specify a zero-length service name, this is common
on some DSL setups.
-It is possible to request a connection to a specific
-access concentrator by its name using the "AC-Name\\Service-Name" syntax.
+It is possible to request a connection to a specific access concentrator,
+and/or set a specific host uniq tag, required by some Internet providers,
+using the "[AC-Name\\][Host-Uniq|]Service-Name" syntax.
+To set a binary Host-Uniq, it must be encoded as a hexadecimal lowercase
+string and prefixed with "0x", eg. "0x6d792d746167" is equivalent to
+"my-tag".
A session request packet will be broadcasted on the Ethernet.
This command uses the
.Dv ngpppoe_init_data
structure shown below.
+For example, the following init data argument can be used to
+connect to "my-isp" service with "my-host" uniq tag, accepting only
+"remote-ac" as access concentrator:
+.Bd -literal -offset indent
+"remote-ac\\my-host|my-isp"
+.Ed
.It Dv NGM_PPPOE_LISTEN Pq Ic pppoe_listen
Tell a nominated newly created hook that its session should enter
the state machine as a server listener.
Index: sys/netgraph/ng_pppoe.c
===================================================================
--- sys/netgraph/ng_pppoe.c
+++ sys/netgraph/ng_pppoe.c
@@ -226,9 +226,11 @@
const struct pppoe_tag *tags[NUMTAGS];
u_int service_len;
u_int ac_name_len;
+ u_int host_uniq_len;
struct datatag service;
struct datatag ac_name;
+ struct datatag host_uniq;
};
typedef struct sess_neg *negp;
@@ -589,18 +591,20 @@
pppoe_finduniq(node_p node, const struct pppoe_tag *tag)
{
hook_p hook = NULL;
- union uniq uniq;
+ sessp sp;
- bcopy(tag + 1, uniq.bytes, sizeof(void *));
/* Cycle through all known hooks. */
LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
/* Skip any nonsession hook. */
if (NG_HOOK_PRIVATE(hook) == NULL)
continue;
- if (uniq.pointer == NG_HOOK_PRIVATE(hook))
+ sp = NG_HOOK_PRIVATE(hook);
+ if (sp->neg->host_uniq_len == ntohs(tag->tag_len) &&
+ bcmp(sp->neg->host_uniq.data, (const char *)(tag + 1),
+ sp->neg->host_uniq_len) == 0)
break;
}
- CTR3(KTR_NET, "%20s: matched %p for %p", __func__, hook, uniq.pointer);
+ CTR3(KTR_NET, "%20s: matched %p for %p", __func__, hook, sp);
return (hook);
}
@@ -848,12 +852,15 @@
* Check the hook exists and is Uninitialised.
* Send a PADI request, and start the timeout logic.
* Store the originator of this message so we can send
- * a success of fail message to them later.
+ * a success or fail message to them later.
* Move the session to SINIT.
* Set up the session to the correct state and
* start it.
*/
- int i, acnlen = 0, acnsep = 0, srvlen;
+ int acnpos, acnlen = 0, acnsep = 0;
+ int hupos, hulen = 0, husep = 0;
+ int i, srvpos, srvlen;
+ acnpos = 0;
for (i = 0; i < ourmsg->data_len; i++) {
if (ourmsg->data[i] == '\\') {
acnlen = i;
@@ -861,15 +868,56 @@
break;
}
}
- srvlen = ourmsg->data_len - acnlen - acnsep;
+ hupos = acnlen + acnsep;
+ for (i = hupos; i < ourmsg->data_len; i++) {
+ if (ourmsg->data[i] == '|') {
+ hulen = i - hupos;
+ husep = 1;
+ break;
+ }
+ }
+ srvpos = hupos + hulen + husep;
+ srvlen = ourmsg->data_len - srvpos;
- bcopy(ourmsg->data, neg->ac_name.data, acnlen);
+ bcopy(ourmsg->data + acnpos, neg->ac_name.data, acnlen);
neg->ac_name_len = acnlen;
+ neg->host_uniq.hdr.tag_type = PTT_HOST_UNIQ;
+ if (hulen == 0) {
+ /* Not provided, generate one */
+ neg->host_uniq.hdr.tag_len = htons(sizeof(sp));
+ bcopy(&sp, neg->host_uniq.data, sizeof(sp));
+ neg->host_uniq_len = sizeof(sp);
+ } else if (hulen > 2 && ourmsg->data[hupos] == '0' &&
+ ourmsg->data[hupos + 1] == 'x' && hulen % 2 == 0) {
+ /* Hex encoded */
+ static const char hexdig[16] = "0123456789abcdef";
+ int j;
+
+ neg->host_uniq.hdr.tag_len = htons((uint16_t)(hulen / 2 - 1));
+ for (i = 0; i < hulen - 2; i++) {
+ for (j = 0;
+ j < 16 &&
+ ourmsg->data[hupos + 2 + i] != hexdig[j];
+ j++);
+ if (j == 16)
+ LEAVE(EINVAL);
+ if (i % 2 == 0)
+ neg->host_uniq.data[i / 2] = j << 4;
+ else
+ neg->host_uniq.data[i / 2] |= j;
+ }
+ neg->host_uniq_len = hulen / 2 - 1;
+ } else {
+ /* Plain string */
+ neg->host_uniq.hdr.tag_len = htons((uint16_t)hulen);
+ bcopy(ourmsg->data + hupos, neg->host_uniq.data, hulen);
+ neg->host_uniq_len = hulen;
+ }
+
neg->service.hdr.tag_type = PTT_SRV_NAME;
neg->service.hdr.tag_len = htons((uint16_t)srvlen);
- bcopy(ourmsg->data + acnlen + acnsep,
- neg->service.data, srvlen);
+ bcopy(ourmsg->data + srvpos, neg->service.data, srvlen);
neg->service_len = srvlen;
pppoe_start(sp);
break;
@@ -879,7 +927,7 @@
* Check the hook exists and is Uninitialised.
* Install the service matching string.
* Store the originator of this message so we can send
- * a success of fail message to them later.
+ * a success or fail message to them later.
* Move the hook to 'LISTENING'
*/
neg->service.hdr.tag_type = PTT_SRV_NAME;
@@ -1061,10 +1109,6 @@
node_p node = NG_HOOK_NODE(hook);
priv_p privp = NG_NODE_PRIVATE(node);
negp neg = sp->neg;
- struct {
- struct pppoe_tag hdr;
- union uniq data;
- } __packed uniqtag;
struct mbuf *m0;
int error;
@@ -1080,11 +1124,8 @@
memcpy((void *)&neg->pkt->pkt_header.eh, &privp->eh,
sizeof(struct ether_header));
neg->pkt->pkt_header.ph.code = PADI_CODE;
- uniqtag.hdr.tag_type = PTT_HOST_UNIQ;
- uniqtag.hdr.tag_len = htons((u_int16_t)sizeof(uniqtag.data));
- uniqtag.data.pointer = sp;
init_tags(sp);
- insert_tag(sp, &uniqtag.hdr);
+ insert_tag(sp, &neg->host_uniq.hdr);
insert_tag(sp, &neg->service.hdr);
if (privp->max_payload.data != 0)
insert_tag(sp, &privp->max_payload.hdr);
@@ -1438,8 +1479,7 @@
* For now simply accept the first we receive.
*/
utag = get_tag(ph, PTT_HOST_UNIQ);
- if ((utag == NULL) ||
- (ntohs(utag->tag_len) != sizeof(sp))) {
+ if (utag == NULL) {
log(LOG_NOTICE, "ng_pppoe[%x]: no host "
"unique field\n", node->nd_ID);
LEAVE(ENETUNREACH);
@@ -1605,8 +1645,7 @@
* set us into Session mode.
*/
utag = get_tag(ph, PTT_HOST_UNIQ);
- if ((utag == NULL) ||
- (ntohs(utag->tag_len) != sizeof(sp))) {
+ if (utag == NULL) {
LEAVE (ENETUNREACH);
}
sendhook = pppoe_finduniq(node, utag);

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 20, 3:25 AM (16 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31817691
Default Alt Text
D9270.id24314.diff (6 KB)

Event Timeline