+++ /dev/null
---- a/pppd/plugins/rp-pppoe/common.c
-+++ b/pppd/plugins/rp-pppoe/common.c
-@@ -119,15 +119,11 @@ sendPADT(PPPoEConnection *conn, char con
- conn->session = 0;
-
- /* If we're using Host-Uniq, copy it over */
-- if (conn->useHostUniq) {
-- PPPoETag hostUniq;
-- pid_t pid = getpid();
-- 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;
-+ if (conn->hostUniq.length) {
-+ int len = ntohs(conn->hostUniq.length);
-+ memcpy(cursor, &conn->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
-@@ -80,13 +80,10 @@ static void
- parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data,
- void *extra)
- {
-- int *val = (int *) extra;
-- if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) {
-- pid_t tmp;
-- memcpy(&tmp, data, len);
-- if (tmp == getpid()) {
-- *val = 1;
-- }
-+ PPPoETag *tag = extra;
-+
-+ if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) {
-+ tag->length = memcmp(data, tag->payload, len);
- }
- }
-
-@@ -104,16 +101,16 @@ parseForHostUniq(UINT16_t type, UINT16_t
- static int
- packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
- {
-- int forMe = 0;
-+ PPPoETag hostUniq = conn->hostUniq;
-
- /* If packet is not directed to our MAC address, forget it */
- if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
-
- /* If we're not using the Host-Unique tag, then accept the packet */
-- if (!conn->useHostUniq) return 1;
-+ if (!conn->hostUniq.length) return 1;
-
-- parsePacket(packet, parseForHostUniq, &forMe);
-- return forMe;
-+ parsePacket(packet, parseForHostUniq, &hostUniq);
-+ return (hostUniq.length == 0);
- }
-
- /**********************************************************************
-@@ -301,16 +298,12 @@ sendPADI(PPPoEConnection *conn)
- }
-
- /* If we're using Host-Uniq, copy it over */
-- if (conn->useHostUniq) {
-- PPPoETag hostUniq;
-- pid_t pid = getpid();
-- 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;
-+ if (conn->hostUniq.length) {
-+ int len = ntohs(conn->hostUniq.length);
-+ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
-+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
-+ cursor += len + TAG_HDR_SIZE;
-+ plen += len + TAG_HDR_SIZE;
- }
-
- /* Add our maximum MTU/MRU */
-@@ -478,16 +471,12 @@ sendPADR(PPPoEConnection *conn)
- cursor += namelen + TAG_HDR_SIZE;
-
- /* If we're using Host-Uniq, copy it over */
-- if (conn->useHostUniq) {
-- PPPoETag hostUniq;
-- pid_t pid = getpid();
-- 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;
-+ if (conn->hostUniq.length) {
-+ int len = ntohs(conn->hostUniq.length);
-+ CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE);
-+ memcpy(cursor, &conn->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,6 @@ PPPOEInitDevice(void)
- conn->ifName = devnam;
- conn->discoverySocket = -1;
- conn->sessionSocket = -1;
-- conn->useHostUniq = 1;
- conn->printACNames = printACNames;
- conn->discoveryTimeout = PADI_TIMEOUT;
- return 1;
-@@ -163,6 +165,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 && !parseHostUniq(host_uniq, &conn->hostUniq))
-+ fatal("Illegal value for host-uniq option");
-+
- 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
-@@ -357,7 +357,7 @@ packetIsForMe(PPPoEConnection *conn, PPP
- if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
-
- /* If we're not using the Host-Unique tag, then accept the packet */
-- if (!conn->useHostUniq) return 1;
-+ if (!conn->hostUniq.length) return 1;
-
- parsePacket(packet, parseForHostUniq, &forMe);
- return forMe;
-@@ -495,16 +495,12 @@ sendPADI(PPPoEConnection *conn)
- cursor += namelen + TAG_HDR_SIZE;
-
- /* If we're using Host-Uniq, copy it over */
-- if (conn->useHostUniq) {
-- PPPoETag hostUniq;
-- pid_t pid = getpid();
-- 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;
-+ if (conn->hostUniq.length) {
-+ int len = ntohs(conn->hostUniq.length);
-+ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
-+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
-+ cursor += len + TAG_HDR_SIZE;
-+ plen += len + TAG_HDR_SIZE;
- }
-
- packet.length = htons(plen);
-@@ -670,7 +666,7 @@ int main(int argc, char *argv[])
- conn->discoveryTimeout = PADI_TIMEOUT;
- conn->discoveryAttempts = MAX_PADI_ATTEMPTS;
-
-- while ((opt = getopt(argc, argv, "I:D:VUQS:C:t:a:h")) > 0) {
-+ while ((opt = getopt(argc, argv, "I:D:VUW:QS:C:t:a:h")) > 0) {
- switch(opt) {
- case 'S':
- conn->serviceName = xstrdup(optarg);
-@@ -697,7 +693,23 @@ int main(int argc, char *argv[])
- }
- break;
- case 'U':
-- conn->useHostUniq = 1;
-+ if(conn->hostUniq.length) {
-+ fprintf(stderr, "-U and -W are mutually exclusive\n");
-+ exit(EXIT_FAILURE);
-+ }
-+ char pidbuf[5];
-+ snprintf(pidbuf, sizeof(pidbuf), "%04x", getpid());
-+ parseHostUniq(pidbuf, &conn->hostUniq);
-+ break;
-+ case 'W':
-+ if(conn->hostUniq.length) {
-+ fprintf(stderr, "-U and -W are mutually exclusive\n");
-+ exit(EXIT_FAILURE);
-+ }
-+ if (!parseHostUniq(optarg, &conn->hostUniq)) {
-+ fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg);
-+ exit(EXIT_FAILURE);
-+ }
- break;
- case 'D':
- conn->debugFile = fopen(optarg, "w");
---- a/pppd/plugins/rp-pppoe/pppoe.h
-+++ b/pppd/plugins/rp-pppoe/pppoe.h
-@@ -21,6 +21,8 @@
-
- #include <stdio.h> /* For FILE */
- #include <sys/types.h> /* For pid_t */
-+#include <ctype.h>
-+#include <string.h>
-
- #include "pppd/pppd.h" /* For error */
-
-@@ -221,7 +223,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 */
-+ PPPoETag hostUniq; /* Use Host-Uniq tag */
- int printACNames; /* Just print AC names */
- FILE *debugFile; /* Debug file for dumping packets */
- int numPADOs; /* Number of PADO packets received */
-@@ -278,6 +280,33 @@ void pppoe_printpkt(PPPoEPacket *packet,
- void (*printer)(void *, char *, ...), void *arg);
- void pppoe_log_packet(const char *prefix, PPPoEPacket *packet);
-
-+static inline int parseHostUniq(const char *uniq, PPPoETag *tag)
-+{
-+ int i, len = strlen(uniq);
-+
-+#define hex(x) \
-+ (((x) <= '9') ? ((x) - '0') : \
-+ (((x) <= 'F') ? ((x) - 'A' + 10) : \
-+ ((x) - 'a' + 10)))
-+
-+ if (len % 2)
-+ return 0;
-+
-+ for (i = 0; i < len; i += 2)
-+ {
-+ if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1]))
-+ return 0;
-+
-+ tag->payload[i / 2] = (char)(16 * hex(uniq[i]) + hex(uniq[i+1]));
-+ }
-+
-+#undef hex
-+
-+ tag->type = htons(TAG_HOST_UNIQ);
-+ tag->length = htons(len / 2);
-+ return 1;
-+}
-+
- #define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0);
-
- #define CHECK_ROOM(cursor, start, len) \