]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/plugins/rp-pppoe/pppoe-discovery.c
pppoe: Custom host-uniq tag
[ppp.git] / pppd / plugins / rp-pppoe / pppoe-discovery.c
index 5afb037a1c74c74448851f6c75a1218810a912db..8b2e946f4d711d516e6f43fc73dbd45405c8b7a9 100644 (file)
@@ -357,7 +357,7 @@ packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
     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:VUQS:C:W:t:a:h")) > 0) {
        switch(opt) {
        case 'S':
            conn->serviceName = xstrdup(optarg);
@@ -697,7 +693,25 @@ 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);
+           } else {
+               pid_t pid = getpid();
+               conn->hostUniq.type = htons(TAG_HOST_UNIQ);
+               conn->hostUniq.length = htons(sizeof(pid));
+               memcpy(conn->hostUniq.payload, &pid, sizeof(pid));
+           }
+           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");
@@ -778,6 +792,7 @@ void usage(void)
            "   -S name        -- Set desired service name.\n"
            "   -C name        -- Set desired access concentrator name.\n"
            "   -U             -- Use Host-Unique to allow multiple PPPoE sessions.\n"
+           "   -W hexvalue    -- Set the Host-Unique to the supplied hex string.\n"
            "   -h             -- Print usage information.\n");
     fprintf(stderr, "\nVersion " RP_VERSION "\n");
 }