From: Matteo Croce <rootkit85@yahoo.it>
Date: Fri, 14 Nov 2014 16:39:59 +0000 (+0000)
Subject: pppd: add option to set custom host-uniq pppoe tag
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=9ee442d0f9e05688f00f764bcb762c0a942e6ef3;p=openwrt%2Fstaging%2Fnbd.git

pppd: add option to set custom host-uniq pppoe tag

SVN-Revision: 43241
---

diff --git a/package/network/services/ppp/files/ppp.sh b/package/network/services/ppp/files/ppp.sh
index 28cdb9cbd6..df404dda39 100755
--- a/package/network/services/ppp/files/ppp.sh
+++ b/package/network/services/ppp/files/ppp.sh
@@ -113,6 +113,7 @@ proto_pppoe_init_config() {
 	ppp_generic_init_config
 	proto_config_add_string "ac"
 	proto_config_add_string "service"
+	proto_config_add_string host_uniq
 }
 
 proto_pppoe_setup() {
@@ -128,12 +129,14 @@ proto_pppoe_setup() {
 
 	json_get_var ac ac
 	json_get_var service service
+	json_get_var host_uniq host_uniq
 
 	ppp_generic_setup "$config" \
 		plugin rp-pppoe.so \
 		${ac:+rp_pppoe_ac "$ac"} \
 		${service:+rp_pppoe_service "$service"} \
-		"nic-$iface"
+		"nic-$iface" \
+		${host_uniq:+host-uniq "$host_uniq"}
 }
 
 proto_pppoe_teardown() {
diff --git a/package/network/services/ppp/patches/520-uniq.patch b/package/network/services/ppp/patches/520-uniq.patch
new file mode 100644
index 0000000000..cbafe4cd5f
--- /dev/null
+++ b/package/network/services/ppp/patches/520-uniq.patch
@@ -0,0 +1,169 @@
+--- a/pppd/plugins/rp-pppoe/common.c
++++ b/pppd/plugins/rp-pppoe/common.c
+@@ -121,13 +121,13 @@ sendPADT(PPPoEConnection *conn, char con
+     /* If we're using Host-Uniq, copy it over */
+     if (conn->useHostUniq) {
+ 	PPPoETag hostUniq;
+-	pid_t pid = getpid();
++	int len = strlen(conn->useHostUniq);
+ 	hostUniq.type = htons(TAG_HOST_UNIQ);
+-	hostUniq.length = htons(sizeof(pid));
+-	memcpy(hostUniq.payload, &pid, sizeof(pid));
+-	memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
+-	cursor += sizeof(pid) + TAG_HDR_SIZE;
+-	plen += sizeof(pid) + TAG_HDR_SIZE;
++	hostUniq.length = htons(len);
++	memcpy(hostUniq.payload, conn->useHostUniq, len);
++	memcpy(cursor, &hostUniq, len + TAG_HDR_SIZE);
++	cursor += len + TAG_HDR_SIZE;
++	plen += len + TAG_HDR_SIZE;
+     }
+ 
+     /* Copy error message */
+--- a/pppd/plugins/rp-pppoe/discovery.c
++++ b/pppd/plugins/rp-pppoe/discovery.c
+@@ -104,7 +104,7 @@ parseForHostUniq(UINT16_t type, UINT16_t
+ static int
+ packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
+ {
+-    int forMe = 0;
++    char *uniq = conn->useHostUniq;
+ 
+     /* If packet is not directed to our MAC address, forget it */
+     if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
+@@ -112,8 +112,8 @@ packetIsForMe(PPPoEConnection *conn, PPP
+     /* If we're not using the Host-Unique tag, then accept the packet */
+     if (!conn->useHostUniq) return 1;
+ 
+-    parsePacket(packet, parseForHostUniq, &forMe);
+-    return forMe;
++    parsePacket(packet, parseForHostUniq, &uniq);
++    return uniq != 0;
+ }
+ 
+ /**********************************************************************
+@@ -303,14 +303,14 @@ sendPADI(PPPoEConnection *conn)
+     /* If we're using Host-Uniq, copy it over */
+     if (conn->useHostUniq) {
+ 	PPPoETag hostUniq;
+-	pid_t pid = getpid();
++	int len = strlen(conn->useHostUniq);
+ 	hostUniq.type = htons(TAG_HOST_UNIQ);
+-	hostUniq.length = htons(sizeof(pid));
+-	memcpy(hostUniq.payload, &pid, sizeof(pid));
+-	CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
+-	memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
+-	cursor += sizeof(pid) + TAG_HDR_SIZE;
+-	plen += sizeof(pid) + TAG_HDR_SIZE;
++	hostUniq.length = htons(len);
++	memcpy(hostUniq.payload, conn->useHostUniq, len);
++	CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
++	memcpy(cursor, &hostUniq, len + TAG_HDR_SIZE);
++	cursor += len + TAG_HDR_SIZE;
++	plen += len + TAG_HDR_SIZE;
+     }
+ 
+     /* Add our maximum MTU/MRU */
+@@ -480,14 +480,14 @@ sendPADR(PPPoEConnection *conn)
+     /* If we're using Host-Uniq, copy it over */
+     if (conn->useHostUniq) {
+ 	PPPoETag hostUniq;
+-	pid_t pid = getpid();
++	int len = strlen(conn->useHostUniq);
+ 	hostUniq.type = htons(TAG_HOST_UNIQ);
+-	hostUniq.length = htons(sizeof(pid));
+-	memcpy(hostUniq.payload, &pid, sizeof(pid));
+-	CHECK_ROOM(cursor, packet.payload, sizeof(pid)+TAG_HDR_SIZE);
+-	memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
+-	cursor += sizeof(pid) + TAG_HDR_SIZE;
+-	plen += sizeof(pid) + TAG_HDR_SIZE;
++	hostUniq.length = htons(len);
++	memcpy(hostUniq.payload, conn->useHostUniq, len);
++	CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE);
++	memcpy(cursor, &hostUniq, len + TAG_HDR_SIZE);
++	cursor += len + TAG_HDR_SIZE;
++	plen += len + TAG_HDR_SIZE;
+     }
+ 
+     /* Add our maximum MTU/MRU */
+--- a/pppd/plugins/rp-pppoe/plugin.c
++++ b/pppd/plugins/rp-pppoe/plugin.c
+@@ -65,6 +65,7 @@ static char *existingSession = NULL;
+ static int printACNames = 0;
+ static char *pppoe_reqd_mac = NULL;
+ unsigned char pppoe_reqd_mac_addr[6];
++static char *host_uniq = NULL;
+ 
+ static int PPPoEDevnameHook(char *cmd, char **argv, int doit);
+ static option_t Options[] = {
+@@ -82,6 +83,8 @@ static option_t Options[] = {
+       "Be verbose about discovered access concentrators"},
+     { "pppoe-mac", o_string, &pppoe_reqd_mac,
+       "Only connect to specified MAC address" },
++    { "host-uniq", o_string, &host_uniq,
++      "Specify custom Host-Uniq" },
+     { NULL }
+ };
+ int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL;
+@@ -107,7 +110,7 @@ PPPOEInitDevice(void)
+     conn->ifName = devnam;
+     conn->discoverySocket = -1;
+     conn->sessionSocket = -1;
+-    conn->useHostUniq = 1;
++    conn->useHostUniq = NULL;
+     conn->printACNames = printACNames;
+     conn->discoveryTimeout = PADI_TIMEOUT;
+     return 1;
+@@ -163,6 +166,9 @@ PPPOEConnectDevice(void)
+     if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
+ 	lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
+ 
++    if(host_uniq)
++	conn->useHostUniq = host_uniq;
++
+     conn->acName = acName;
+     conn->serviceName = pppd_pppoe_service;
+     strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
+--- a/pppd/plugins/rp-pppoe/pppoe-discovery.c
++++ b/pppd/plugins/rp-pppoe/pppoe-discovery.c
+@@ -641,7 +641,7 @@ int main(int argc, char *argv[])
+ 
+     memset(conn, 0, sizeof(PPPoEConnection));
+ 
+-    while ((opt = getopt(argc, argv, "I:D:VUAS:C:h")) > 0) {
++    while ((opt = getopt(argc, argv, "I:D:VUW:AS:C:h")) > 0) {
+ 	switch(opt) {
+ 	case 'S':
+ 	    conn->serviceName = xstrdup(optarg);
+@@ -650,7 +650,19 @@ int main(int argc, char *argv[])
+ 	    conn->acName = xstrdup(optarg);
+ 	    break;
+ 	case 'U':
+-	    conn->useHostUniq = 1;
++	    if(conn->useHostUniq) {
++		fprintf(stderr, "-U and -W are mutually exclusive\n");
++		exit(EXIT_FAILURE);
++	    }
++	    conn->useHostUniq = malloc(12);
++	    snprintf(conn->useHostUniq, 12, "%d", getpid());
++	    break;
++	case 'W':
++	    if(conn->useHostUniq) {
++		fprintf(stderr, "-U and -W are mutually exclusive\n");
++		exit(EXIT_FAILURE);
++	    }
++	    conn->useHostUniq = xstrdup(optarg);
+ 	    break;
+ 	case 'D':
+ 	    conn->debugFile = fopen(optarg, "w");
+--- a/pppd/plugins/rp-pppoe/pppoe.h
++++ b/pppd/plugins/rp-pppoe/pppoe.h
+@@ -224,7 +224,7 @@ typedef struct PPPoEConnectionStruct {
+     char *serviceName;		/* Desired service name, if any */
+     char *acName;		/* Desired AC name, if any */
+     int synchronous;		/* Use synchronous PPP */
+-    int useHostUniq;		/* Use Host-Uniq tag */
++    char *useHostUniq;		/* Use Host-Uniq tag */
+     int printACNames;		/* Just print AC names */
+     FILE *debugFile;		/* Debug file for dumping packets */
+     int numPADOs;		/* Number of PADO packets received */