X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Fplugins%2Fpppoe%2Fdiscovery.c;h=b32b0c891dcd89c5fb46ebe402adc698f9a0611f;hb=HEAD;hp=bd281bdb863b1a6be44e6c9530f99e7b6f05997e;hpb=92c5612fdb77e83e49c524ae46110c129e13429e;p=ppp.git diff --git a/pppd/plugins/pppoe/discovery.c b/pppd/plugins/pppoe/discovery.c index bd281bd..ccb88b2 100644 --- a/pppd/plugins/pppoe/discovery.c +++ b/pppd/plugins/pppoe/discovery.c @@ -12,14 +12,14 @@ static char const RCSID[] = "$Id: discovery.c,v 1.6 2008/06/15 04:35:50 paulus Exp $"; #ifdef HAVE_CONFIG_H -#include +#include "config.h" #endif #define _GNU_SOURCE 1 #include "pppoe.h" -#include "pppd/pppd.h" -#include "pppd/fsm.h" -#include "pppd/lcp.h" +#include +#include +#include #include #include @@ -44,6 +44,15 @@ static char const RCSID[] = #include +#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) { @@ -142,7 +151,7 @@ parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, switch(type) { case TAG_AC_NAME: pc->seenACName = 1; - if (conn->printACNames) { + if (pppoe_verbose >= 1) { info("Access-Concentrator: %.*s", (int) len, data); } if (conn->acName && len == strlen(conn->acName) && @@ -152,30 +161,60 @@ 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; idiscoveryState != 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; idiscoveryState != 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) { - if (lcp_allowoptions[0].mru > mru) - lcp_allowoptions[0].mru = mru; - if (lcp_wantoptions[0].mru > mru) - lcp_wantoptions[0].mru = mru; + 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) + conn->mru = mru; conn->seenMaxPayload = 1; } } @@ -215,17 +254,19 @@ 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)) { memcpy(&mru, data, sizeof(mru)); mru = ntohs(mru); if (mru >= ETH_PPPOE_MTU) { - if (lcp_allowoptions[0].mru > mru) - lcp_allowoptions[0].mru = mru; - if (lcp_wantoptions[0].mru > mru) - lcp_wantoptions[0].mru = mru; + if (conn->mtu > mru) + conn->mtu = mru; + if (conn->mru > mru) + conn->mru = mru; conn->seenMaxPayload = 1; } } @@ -310,9 +351,9 @@ sendPADI(PPPoEConnection *conn) } /* Add our maximum MTU/MRU */ - if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) { + if (MIN(conn->mtu, conn->mru) > ETH_PPPOE_MTU) { PPPoETag maxPayload; - UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru)); + UINT16_t mru = htons(MIN(conn->mtu, conn->mru)); maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD); maxPayload.length = htons(sizeof(mru)); memcpy(maxPayload.payload, &mru, sizeof(mru)); @@ -355,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"); @@ -373,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"); @@ -383,6 +423,7 @@ waitForPADO(PPPoEConnection *conn, int timeout) return; /* Timed out */ } + conn->error = 0; /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); @@ -412,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; @@ -423,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); } /*********************************************************************** @@ -483,9 +533,9 @@ sendPADR(PPPoEConnection *conn) } /* Add our maximum MTU/MRU */ - if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) { + if (MIN(conn->mtu, conn->mru) > ETH_PPPOE_MTU) { PPPoETag maxPayload; - UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru)); + UINT16_t mru = htons(MIN(conn->mtu, conn->mru)); maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD); maxPayload.length = htons(sizeof(mru)); memcpy(maxPayload.payload, &mru, sizeof(mru)); @@ -554,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"); @@ -609,24 +659,23 @@ waitForPADS(PPPoEConnection *conn, int timeout) } /********************************************************************** -*%FUNCTION: discovery +*%FUNCTION: discovery1 *%ARGUMENTS: * conn -- PPPoE connection info structure *%RETURNS: * Nothing *%DESCRIPTION: -* Performs the PPPoE discovery phase +* Performs the PPPoE discovery phase 1 ***********************************************************************/ void -discovery(PPPoEConnection *conn) +discovery1(PPPoEConnection *conn) { int padiAttempts = 0; - int padrAttempts = 0; int timeout = conn->discoveryTimeout; 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; @@ -638,11 +687,26 @@ discovery(PPPoEConnection *conn) timeout *= 2; } while (conn->discoveryState == STATE_SENT_PADI); +} + +/********************************************************************** +*%FUNCTION: discovery2 +*%ARGUMENTS: +* conn -- PPPoE connection info structure +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Performs the PPPoE discovery phase 2 +***********************************************************************/ +void +discovery2(PPPoEConnection *conn) +{ + int padrAttempts = 0; + int timeout = conn->discoveryTimeout; - timeout = conn->discoveryTimeout; 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; @@ -656,10 +720,10 @@ discovery(PPPoEConnection *conn) if (!conn->seenMaxPayload) { /* RFC 4638: MUST limit MTU/MRU to 1492 */ - if (lcp_allowoptions[0].mru > ETH_PPPOE_MTU) - lcp_allowoptions[0].mru = ETH_PPPOE_MTU; - if (lcp_wantoptions[0].mru > ETH_PPPOE_MTU) - lcp_wantoptions[0].mru = ETH_PPPOE_MTU; + if (conn->mtu > ETH_PPPOE_MTU) + conn->mtu = ETH_PPPOE_MTU; + if (conn->mru > ETH_PPPOE_MTU) + conn->mru = ETH_PPPOE_MTU; } /* We're done. */