ale updated this revision to Diff 24314.
ale added a comment.
This revision now requires review to proceed.


  Fixed typos and improved man page.

REPOSITORY
  rS FreeBSD src repository

CHANGES SINCE LAST UPDATE
  https://reviews.freebsd.org/D9270?vs=24264&id=24314

REVISION DETAIL
  https://reviews.freebsd.org/D9270

AFFECTED FILES
  share/man/man4/ng_pppoe.4
  sys/netgraph/ng_pppoe.c

EMAIL PREFERENCES
  https://reviews.freebsd.org/settings/panel/emailpreferences/

To: ale, #network, #manpages, julian
Cc: mandree, imp, freebsd-net-list
diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c
--- a/sys/netgraph/ng_pppoe.c
+++ b/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,28 +852,72 @@
 			 * 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;
 					acnsep = 1;
 					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);
diff --git a/share/man/man4/ng_pppoe.4 b/share/man/man4/ng_pppoe.4
--- a/share/man/man4/ng_pppoe.4
+++ b/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.

_______________________________________________
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to