]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/plugins/pppoe/discovery.c
pppd.8: Document netmask option
[ppp.git] / pppd / plugins / pppoe / discovery.c
index 1d3d12ba5884ad39099dcddc4c70c3e478b90951..ccb88b2d6bf576e775758add1ec8af397393cb1d 100644 (file)
 static char const RCSID[] =
 "$Id: discovery.c,v 1.6 2008/06/15 04:35:50 paulus Exp $";
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #define _GNU_SOURCE 1
 #include "pppoe.h"
-#include "pppd/pppd.h"
-#include "pppd/fsm.h"
-#include "pppd/lcp.h"
+#include <pppd/pppd.h>
+#include <pppd/fsm.h>
+#include <pppd/lcp.h>
 
 #include <string.h>
 #include <stdlib.h>
@@ -40,6 +44,15 @@ static char const RCSID[] =
 
 #include <signal.h>
 
+#ifdef PLUGIN
+#define signaled(x) ppp_signaled(x)
+#define get_time(x) ppp_get_time(x)
+#else
+int signaled(int signal);
+int get_time(struct timeval *tv);
+
+#endif
+
 /* Calculate time remaining until *exp, return 0 if now >= *exp */
 static int time_left(struct timeval *diff, struct timeval *exp)
 {
@@ -148,26 +161,56 @@ parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data,
        break;
     case TAG_SERVICE_NAME:
        pc->seenServiceName = 1;
+       if (pppoe_verbose >= 1 && len > 0) {
+           info("Service-Name: %.*s", (int) len, data);
+       }
        if (conn->serviceName && len == strlen(conn->serviceName) &&
            !strncmp((char *) data, conn->serviceName, len)) {
            pc->serviceNameOK = 1;
        }
        break;
     case TAG_AC_COOKIE:
-       conn->cookie.type = htons(type);
-       conn->cookie.length = htons(len);
-       memcpy(conn->cookie.payload, data, len);
+       if (pppoe_verbose >= 1) {
+           char buffer[100];
+           char *ptr = buffer;
+           ptr += sprintf(ptr, "Cookie:");
+           /* Print first 20 bytes of cookie */
+           for (i=0; i<len && i < 20; i++) {
+               ptr += sprintf(ptr, " %02x", (unsigned) data[i]);
+           }
+           if (i < len) ptr += sprintf(ptr, "...");
+           info(buffer);
+       }
+       if (conn->discoveryState != STATE_RECEIVED_PADO) {
+           conn->cookie.type = htons(type);
+           conn->cookie.length = htons(len);
+           memcpy(conn->cookie.payload, data, len);
+       }
        break;
     case TAG_RELAY_SESSION_ID:
-       conn->relayId.type = htons(type);
-       conn->relayId.length = htons(len);
-       memcpy(conn->relayId.payload, data, len);
+       if (pppoe_verbose >= 1) {
+           char buffer[100];
+           char *ptr = buffer;
+           ptr += sprintf(ptr, "Relay-ID:");
+           /* Print first 20 bytes of relay ID */
+           for (i=0; i<len && i < 20; i++) {
+               ptr += printf(ptr, " %02x", (unsigned) data[i]);
+           }
+           if (i < len) ptr += printf(ptr, "...");
+           info(buffer);
+       }
+       if (conn->discoveryState != STATE_RECEIVED_PADO) {
+           conn->relayId.type = htons(type);
+           conn->relayId.length = htons(len);
+           memcpy(conn->relayId.payload, data, len);
+       }
        break;
     case TAG_PPP_MAX_PAYLOAD:
        if (len == sizeof(mru)) {
            memcpy(&mru, data, sizeof(mru));
            mru = ntohs(mru);
-           if (mru >= ETH_PPPOE_MTU) {
+           info("Max-Payload: %u", (unsigned) mru);
+           if (mru >= ETH_PPPOE_MTU && conn->discoveryState != STATE_RECEIVED_PADO) {
                if (conn->mtu > mru)
                    conn->mtu = mru;
                if (conn->mru > mru)
@@ -211,7 +254,9 @@ parsePADSTags(UINT16_t type, UINT16_t len, unsigned char *data,
     UINT16_t mru;
     switch(type) {
     case TAG_SERVICE_NAME:
-       dbglog("PADS: Service-Name: '%.*s'", (int) len, data);
+       if (pppoe_verbose >= 1 && len > 0) {
+           info("PADS: Service-Name: '%.*s'", (int) len, data);
+       }
        break;
     case TAG_PPP_MAX_PAYLOAD:
        if (len == sizeof(mru)) {
@@ -351,7 +396,6 @@ waitForPADO(PPPoEConnection *conn, int timeout)
     pc.seenACName    = 0;
     pc.seenServiceName = 0;
     conn->seenMaxPayload = 0;
-    conn->error = 0;
 
     if (get_time(&expire_at) < 0) {
        error("get_time (waitForPADO): %m");
@@ -369,7 +413,7 @@ waitForPADO(PPPoEConnection *conn, int timeout)
 
            while(1) {
                r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
-               if (r >= 0 || errno != EINTR || got_sigterm) break;
+               if (r >= 0 || errno != EINTR || signaled(SIGTERM)) break;
            }
            if (r < 0) {
                error("select (waitForPADO): %m");
@@ -379,6 +423,7 @@ waitForPADO(PPPoEConnection *conn, int timeout)
                return;         /* Timed out */
        }
 
+       conn->error = 0;
        /* Get the packet */
        receivePacket(conn->discoverySocket, &packet, &len);
 
@@ -408,9 +453,9 @@ waitForPADO(PPPoEConnection *conn, int timeout)
                continue;
            }
            if (parsePacket(&packet, parsePADOTags, &pc) < 0)
-               return;
+               continue;
            if (conn->error)
-               return;
+               continue;
            if (!pc.seenACName) {
                error("Ignoring PADO packet with no AC-Name tag");
                continue;
@@ -419,14 +464,23 @@ waitForPADO(PPPoEConnection *conn, int timeout)
                error("Ignoring PADO packet with no Service-Name tag");
                continue;
            }
+           if (pppoe_verbose >= 1) {
+               info("AC-Ethernet-Address: %02x:%02x:%02x:%02x:%02x:%02x",
+                      (unsigned) packet.ethHdr.h_source[0],
+                      (unsigned) packet.ethHdr.h_source[1],
+                      (unsigned) packet.ethHdr.h_source[2],
+                      (unsigned) packet.ethHdr.h_source[3],
+                      (unsigned) packet.ethHdr.h_source[4],
+                      (unsigned) packet.ethHdr.h_source[5]);
+               info("--------------------------------------------------");
+           }
            conn->numPADOs++;
-           if (pc.acNameOK && pc.serviceNameOK) {
+           if (pc.acNameOK && pc.serviceNameOK && conn->discoveryState != STATE_RECEIVED_PADO) {
                memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN);
                conn->discoveryState = STATE_RECEIVED_PADO;
-               break;
            }
        }
-    } while (conn->discoveryState != STATE_RECEIVED_PADO);
+    } while (pppoe_verbose >= 1 || conn->discoveryState != STATE_RECEIVED_PADO);
 }
 
 /***********************************************************************
@@ -550,7 +604,7 @@ waitForPADS(PPPoEConnection *conn, int timeout)
 
            while(1) {
                r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
-               if (r >= 0 || errno != EINTR || got_sigterm) break;
+               if (r >= 0 || errno != EINTR || signaled(SIGTERM)) break;
            }
            if (r < 0) {
                error("select (waitForPADS): %m");
@@ -621,7 +675,7 @@ discovery1(PPPoEConnection *conn)
 
     do {
        padiAttempts++;
-       if (got_sigterm || padiAttempts > conn->discoveryAttempts) {
+       if (signaled(SIGTERM) || padiAttempts > conn->discoveryAttempts) {
            warn("Timeout waiting for PADO packets");
            close(conn->discoverySocket);
            conn->discoverySocket = -1;
@@ -652,7 +706,7 @@ discovery2(PPPoEConnection *conn)
 
     do {
        padrAttempts++;
-       if (got_sigterm || padrAttempts > conn->discoveryAttempts) {
+       if (signaled(SIGTERM) || padrAttempts > conn->discoveryAttempts) {
            warn("Timeout waiting for PADS packets");
            close(conn->discoverySocket);
            conn->discoverySocket = -1;