diff options
author | Paul Mackerras <paulus@ozlabs.org> | 2021-11-26 11:05:06 +1100 |
---|---|---|
committer | Paul Mackerras <paulus@ozlabs.org> | 2021-11-26 11:05:06 +1100 |
commit | 032020241d270c53dff479a7b0eb7fe487c56a78 (patch) | |
tree | c095da40353ef151c7f96f262a14c094747ae9b8 /pppd | |
parent | 7f8c1a1f8e486b232340fd9a0a19c5d34f1c5ae0 (diff) | |
parent | e94a5fcb7620cf399ad1c2666b8093d6ca3df24b (diff) | |
download | ppp-032020241d270c53dff479a7b0eb7fe487c56a78.tar.gz |
Merge branch 'pppoe-discovery' of https://github.com/pali/ppp
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Diffstat (limited to 'pppd')
-rw-r--r-- | pppd/plugins/pppoe/Makefile.am | 2 | ||||
-rw-r--r-- | pppd/plugins/pppoe/common.c | 53 | ||||
-rw-r--r-- | pppd/plugins/pppoe/debug.c | 149 | ||||
-rw-r--r-- | pppd/plugins/pppoe/discovery.c | 127 | ||||
-rw-r--r-- | pppd/plugins/pppoe/plugin.c | 34 | ||||
-rw-r--r-- | pppd/plugins/pppoe/pppoe-discovery.c | 676 | ||||
-rw-r--r-- | pppd/plugins/pppoe/pppoe.h | 16 | ||||
-rw-r--r-- | pppd/pppd.8 | 5 |
8 files changed, 260 insertions, 802 deletions
diff --git a/pppd/plugins/pppoe/Makefile.am b/pppd/plugins/pppoe/Makefile.am index e3c01cd..0d70380 100644 --- a/pppd/plugins/pppoe/Makefile.am +++ b/pppd/plugins/pppoe/Makefile.am @@ -11,4 +11,4 @@ pppoe_la_LDFLAGS = -module -avoid-version pppoe_la_SOURCES = plugin.c discovery.c if.c common.c pppoe_discovery_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/include -pppoe_discovery_SOURCES = pppoe-discovery.c debug.c +pppoe_discovery_SOURCES = pppoe-discovery.c discovery.c if.c common.c diff --git a/pppd/plugins/pppoe/common.c b/pppd/plugins/pppoe/common.c index 64bed1a..8b0e636 100644 --- a/pppd/plugins/pppoe/common.c +++ b/pppd/plugins/pppoe/common.c @@ -164,6 +164,42 @@ sendPADT(PPPoEConnection *conn, char const *msg) info("Sent PADT"); } +static void +pppoe_printpkt_hex(void (*printer)(void *, char *, ...), void *arg, unsigned char const *buf, int len) +{ + int i; + int base; + + /* do NOT dump PAP packets */ + if (len >= 2 && buf[0] == 0xC0 && buf[1] == 0x23) { + printer(arg, "(PAP Authentication Frame -- Contents not dumped)\n"); + return; + } + + for (base=0; base<len; base += 16) { + for (i=base; i<base+16; i++) { + if (i < len) { + printer(arg, "%02x ", (unsigned) buf[i]); + } else { + printer(arg, " "); + } + } + printer(arg, " "); + for (i=base; i<base+16; i++) { + if (i < len) { + if (isprint(buf[i])) { + printer(arg, "%c", buf[i]); + } else { + printer(arg, "."); + } + } else { + break; + } + } + printer(arg, "\n"); + } +} + #define EH(x) (x)[0], (x)[1], (x)[2], (x)[3], (x)[4], (x)[5] /* Print out a PPPOE packet for debugging */ @@ -171,7 +207,7 @@ void pppoe_printpkt(PPPoEPacket *packet, void (*printer)(void *, char *, ...), void *arg) { int len = ntohs(packet->length); - int i, tag, tlen, text; + int i, j, tag, tlen, text; switch (ntohs(packet->ethHdr.h_proto)) { case ETH_PPPOE_DISCOVERY: @@ -211,6 +247,8 @@ void pppoe_printpkt(PPPoEPacket *packet, printer(arg, " dst %02x:%02x:%02x:%02x:%02x:%02x ", EH(packet->ethHdr.h_dest)); printer(arg, " src %02x:%02x:%02x:%02x:%02x:%02x\n", EH(packet->ethHdr.h_source)); + if (pppoe_verbose >= 2) + pppoe_printpkt_hex(printer, arg, packet->payload, ntohs(packet->length)); if (ntohs(packet->ethHdr.h_proto) != ETH_PPPOE_DISCOVERY) return; @@ -266,12 +304,13 @@ void pppoe_printpkt(PPPoEPacket *packet, } if (tlen) { if (text) - printer(arg, " %.*v", tlen, &packet->payload[i]); - else if (tlen <= 32) - printer(arg, " %.*B", tlen, &packet->payload[i]); - else - printer(arg, " %.32B... (length %d)", - &packet->payload[i], tlen); + printer(arg, " %.*s", tlen, &packet->payload[i]); + else { + for (j = 0; j < tlen && j < 32; j++) + printer(arg, " %02x", (unsigned) *(&packet->payload[i]+j)); + if (j < tlen) + printer(arg, "... (length %d)", tlen); + } } printer(arg, "]"); } diff --git a/pppd/plugins/pppoe/debug.c b/pppd/plugins/pppoe/debug.c deleted file mode 100644 index 3478b5f..0000000 --- a/pppd/plugins/pppoe/debug.c +++ /dev/null @@ -1,149 +0,0 @@ -/*********************************************************************** -* -* debug.c -* -* Implementation of user-space PPPoE redirector for Linux. -* -* Functions for printing debugging information -* -* Copyright (C) 2000 by Roaring Penguin Software Inc. -* -* This program may be distributed according to the terms of the GNU -* General Public License, version 2 or (at your option) any later version. -* -***********************************************************************/ - -static char const RCSID[] = -"$Id: debug.c,v 1.2 2008/06/09 08:34:23 paulus Exp $"; - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "pppoe.h" -#include <sys/time.h> -#include <time.h> -#include <unistd.h> -#include <ctype.h> - -/********************************************************************** -*%FUNCTION: dumpHex -*%ARGUMENTS: -* fp -- file to dump to -* buf -- buffer to dump -* len -- length of data -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Dumps buffer to fp in an easy-to-read format -***********************************************************************/ -void -dumpHex(FILE *fp, unsigned char const *buf, int len) -{ - int i; - int base; - - if (!fp) return; - - /* do NOT dump PAP packets */ - if (len >= 2 && buf[0] == 0xC0 && buf[1] == 0x23) { - fprintf(fp, "(PAP Authentication Frame -- Contents not dumped)\n"); - return; - } - - for (base=0; base<len; base += 16) { - for (i=base; i<base+16; i++) { - if (i < len) { - fprintf(fp, "%02x ", (unsigned) buf[i]); - } else { - fprintf(fp, " "); - } - } - fprintf(fp, " "); - for (i=base; i<base+16; i++) { - if (i < len) { - if (isprint(buf[i])) { - fprintf(fp, "%c", buf[i]); - } else { - fprintf(fp, "."); - } - } else { - break; - } - } - fprintf(fp, "\n"); - } -} - -/********************************************************************** -*%FUNCTION: dumpPacket -*%ARGUMENTS: -* fp -- file to dump to -* packet -- a PPPoE packet -* dir -- either SENT or RCVD -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Dumps the PPPoE packet to fp in an easy-to-read format -***********************************************************************/ -void -dumpPacket(FILE *fp, PPPoEPacket *packet, char const *dir) -{ - int len = ntohs(packet->length); - - /* Sheesh... printing times is a pain... */ - struct timeval tv; - time_t now; - int millisec; - struct tm *lt; - char timebuf[256]; - - UINT16_t type = etherType(packet); - if (!fp) return; - gettimeofday(&tv, NULL); - now = (time_t) tv.tv_sec; - millisec = tv.tv_usec / 1000; - lt = localtime(&now); - strftime(timebuf, 256, "%H:%M:%S", lt); - fprintf(fp, "%s.%03d %s PPPoE ", timebuf, millisec, dir); - if (type == Eth_PPPOE_Discovery) { - fprintf(fp, "Discovery (%x) ", (unsigned) type); - } else if (type == Eth_PPPOE_Session) { - fprintf(fp, "Session (%x) ", (unsigned) type); - } else { - fprintf(fp, "Unknown (%x) ", (unsigned) type); - } - - switch(packet->code) { - case CODE_PADI: fprintf(fp, "PADI "); break; - case CODE_PADO: fprintf(fp, "PADO "); break; - case CODE_PADR: fprintf(fp, "PADR "); break; - case CODE_PADS: fprintf(fp, "PADS "); break; - case CODE_PADT: fprintf(fp, "PADT "); break; - case CODE_PADM: fprintf(fp, "PADM "); break; - case CODE_PADN: fprintf(fp, "PADN "); break; - case CODE_SESS: fprintf(fp, "SESS "); break; - } - - fprintf(fp, "sess-id %d length %d\n", - (int) ntohs(packet->session), - len); - - /* Ugly... I apologize... */ - fprintf(fp, - "SourceAddr %02x:%02x:%02x:%02x:%02x:%02x " - "DestAddr %02x:%02x:%02x:%02x:%02x:%02x\n", - (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], - (unsigned) packet->ethHdr.h_dest[0], - (unsigned) packet->ethHdr.h_dest[1], - (unsigned) packet->ethHdr.h_dest[2], - (unsigned) packet->ethHdr.h_dest[3], - (unsigned) packet->ethHdr.h_dest[4], - (unsigned) packet->ethHdr.h_dest[5]); - dumpHex(fp, packet->payload, ntohs(packet->length)); -} diff --git a/pppd/plugins/pppoe/discovery.c b/pppd/plugins/pppoe/discovery.c index bd281bd..b32b0c8 100644 --- a/pppd/plugins/pppoe/discovery.c +++ b/pppd/plugins/pppoe/discovery.c @@ -142,7 +142,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 +152,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; 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) { - 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 +245,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 +342,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 +387,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"); @@ -383,6 +414,7 @@ waitForPADO(PPPoEConnection *conn, int timeout) return; /* Timed out */ } + conn->error = 0; /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); @@ -412,9 +444,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 +455,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 +524,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)); @@ -609,19 +650,18 @@ 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 { @@ -638,8 +678,23 @@ 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) { @@ -656,10 +711,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. */ diff --git a/pppd/plugins/pppoe/plugin.c b/pppd/plugins/pppoe/plugin.c index 8bcd1f8..c534507 100644 --- a/pppd/plugins/pppoe/plugin.c +++ b/pppd/plugins/pppoe/plugin.c @@ -68,7 +68,7 @@ extern int new_style_driver; char *pppd_pppoe_service = NULL; static char *acName = NULL; static char *existingSession = NULL; -static int printACNames = 0; +int pppoe_verbose = 0; static char *pppoe_reqd_mac = NULL; unsigned char pppoe_reqd_mac_addr[6]; static char *pppoe_host_uniq; @@ -93,9 +93,9 @@ static option_t Options[] = { "Attach to existing session (sessid:macaddr)" }, { "rp_pppoe_sess", o_string, &existingSession, "Legacy alias for pppoe-sess", OPT_ALIAS }, - { "pppoe-verbose", o_int, &printACNames, + { "pppoe-verbose", o_int, &pppoe_verbose, "Be verbose about discovered access concentrators" }, - { "rp_pppoe_verbose", o_int, &printACNames, + { "rp_pppoe_verbose", o_int, &pppoe_verbose, "Legacy alias for pppoe-verbose", OPT_ALIAS }, { "pppoe-mac", o_string, &pppoe_reqd_mac, "Only connect to specified MAC address" }, @@ -132,7 +132,6 @@ PPPOEInitDevice(void) conn->ifName = devnam; conn->discoverySocket = -1; conn->sessionSocket = -1; - conn->printACNames = printACNames; conn->discoveryTimeout = pppoe_padi_timeout; conn->discoveryAttempts = pppoe_padi_attempts; return 1; @@ -166,8 +165,8 @@ PPPOEConnectDevice(void) } /* Restore configuration */ - lcp_allowoptions[0].mru = conn->mtu; - lcp_wantoptions[0].mru = conn->mru; + lcp_allowoptions[0].mru = conn->mtu = conn->storedmtu; + lcp_wantoptions[0].mru = conn->mru = conn->storedmru; /* Update maximum MRU */ s = socket(AF_INET, SOCK_DGRAM, 0); @@ -184,9 +183,9 @@ PPPOEConnectDevice(void) close(s); if (lcp_allowoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD) - lcp_allowoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD; + lcp_allowoptions[0].mru = conn->mtu = ifr.ifr_mtu - TOTAL_OVERHEAD; if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD) - lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD; + lcp_wantoptions[0].mru = conn->mru = ifr.ifr_mtu - TOTAL_OVERHEAD; if (pppoe_host_uniq) { if (!parseHostUniq(pppoe_host_uniq, &conn->hostUniq)) @@ -221,9 +220,20 @@ PPPOEConnectDevice(void) error("Failed to create PPPoE discovery socket: %m"); goto errout; } - discovery(conn); + discovery1(conn); + /* discovery1() may update conn->mtu and conn->mru */ + lcp_allowoptions[0].mru = conn->mtu; + lcp_wantoptions[0].mru = conn->mru; + if (conn->discoveryState != STATE_RECEIVED_PADO) { + error("Unable to complete PPPoE Discovery phase 1"); + goto errout; + } + discovery2(conn); + /* discovery2() may update conn->mtu and conn->mru */ + lcp_allowoptions[0].mru = conn->mtu; + lcp_wantoptions[0].mru = conn->mru; if (conn->discoveryState != STATE_SESSION) { - error("Unable to complete PPPoE Discovery"); + error("Unable to complete PPPoE Discovery phase 2"); goto errout; } } @@ -452,8 +462,8 @@ void pppoe_check_options(void) lcp_wantoptions[0].mru = MAX_PPPOE_MTU; /* Save configuration */ - conn->mtu = lcp_allowoptions[0].mru; - conn->mru = lcp_wantoptions[0].mru; + conn->storedmtu = lcp_allowoptions[0].mru; + conn->storedmru = lcp_wantoptions[0].mru; ccp_allowoptions[0].deflate = 0; ccp_wantoptions[0].deflate = 0; diff --git a/pppd/plugins/pppoe/pppoe-discovery.c b/pppd/plugins/pppoe/pppoe-discovery.c index 96d6333..1fe999d 100644 --- a/pppd/plugins/pppoe/pppoe-discovery.c +++ b/pppd/plugins/pppoe/pppoe-discovery.c @@ -20,6 +20,7 @@ #include <errno.h> #include <string.h> #include <time.h> +#include <signal.h> #include "pppoe.h" @@ -49,611 +50,130 @@ #include <net/if_arp.h> #endif -char *xstrdup(const char *s); -void usage(void); +int debug; +int got_sigterm; +int pppoe_verbose; +static FILE *debugFile; -void die(int status) -{ - exit(status); -} - -void error(char *fmt, ...) +void +fatal(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); vfprintf(stderr, fmt, pvar); va_end(pvar); + fputc('\n', stderr); + exit(1); } -/* Initialize frame types to RFC 2516 values. Some broken peers apparently - use different frame types... sigh... */ - -UINT16_t Eth_PPPOE_Discovery = ETH_PPPOE_DISCOVERY; -UINT16_t Eth_PPPOE_Session = ETH_PPPOE_SESSION; - -/********************************************************************** -*%FUNCTION: etherType -*%ARGUMENTS: -* packet -- a received PPPoE packet -*%RETURNS: -* ethernet packet type (see /usr/include/net/ethertypes.h) -*%DESCRIPTION: -* Checks the ethernet packet header to determine its type. -* We should only be receveing DISCOVERY and SESSION types if the BPF -* is set up correctly. Logs an error if an unexpected type is received. -* Note that the ethernet type names come from "pppoe.h" and the packet -* packet structure names use the LINUX dialect to maintain consistency -* with the rest of this file. See the BSD section of "pppoe.h" for -* translations of the data structure names. -***********************************************************************/ -UINT16_t -etherType(PPPoEPacket *packet) -{ - UINT16_t type = (UINT16_t) ntohs(packet->ethHdr.h_proto); - if (type != Eth_PPPOE_Discovery && type != Eth_PPPOE_Session) { - fprintf(stderr, "Invalid ether type 0x%x\n", type); - } - return type; -} - -/********************************************************************** -*%FUNCTION: openInterface -*%ARGUMENTS: -* ifname -- name of interface -* type -- Ethernet frame type -* hwaddr -- if non-NULL, set to the hardware address -*%RETURNS: -* A raw socket for talking to the Ethernet card. Exits on error. -*%DESCRIPTION: -* Opens a raw Ethernet socket -***********************************************************************/ -int -openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) +void +error(char *fmt, ...) { - int optval=1; - int fd; - struct ifreq ifr; - int domain, stype; - -#ifdef HAVE_STRUCT_SOCKADDR_LL - struct sockaddr_ll sa; -#else - struct sockaddr sa; -#endif - - memset(&sa, 0, sizeof(sa)); - -#ifdef HAVE_STRUCT_SOCKADDR_LL - domain = PF_PACKET; - stype = SOCK_RAW; -#else - domain = PF_INET; - stype = SOCK_PACKET; -#endif - - if ((fd = socket(domain, stype, htons(type))) < 0) { - /* Give a more helpful message for the common error case */ - if (errno == EPERM) { - fatal("Cannot create raw socket -- pppoe must be run as root."); - } - fatalSys("socket"); - } - - if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) { - fatalSys("setsockopt"); - } - - /* Fill in hardware address */ - if (hwaddr) { - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { - fatalSys("ioctl(SIOCGIFHWADDR)"); - } - memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); -#ifdef ARPHRD_ETHER - if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { - fatal("Interface %.16s is not Ethernet", ifname); - } -#endif - if (NOT_UNICAST(hwaddr)) { - fatal("Interface %.16s has broadcast/multicast MAC address??", ifname); - } - } - - /* Sanity check on MTU */ - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { - fatalSys("ioctl(SIOCGIFMTU)"); - } - if (ifr.ifr_mtu < ETH_DATA_LEN) { - fprintf(stderr, "Interface %.16s has MTU of %d -- should be %d.\n", - ifname, ifr.ifr_mtu, ETH_DATA_LEN); - fprintf(stderr, "You may have serious connection problems.\n"); - } - -#ifdef HAVE_STRUCT_SOCKADDR_LL - /* Get interface index */ - sa.sll_family = AF_PACKET; - sa.sll_protocol = htons(type); - - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ - 1] = 0; - if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { - fatalSys("ioctl(SIOCFIGINDEX): Could not get interface index"); - } - sa.sll_ifindex = ifr.ifr_ifindex; - -#else - strcpy(sa.sa_data, ifname); -#endif - - /* We're only interested in packets on specified interface */ - if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { - fatalSys("bind"); - } - - return fd; + va_list pvar; + va_start(pvar, fmt); + vfprintf(stderr, fmt, pvar); + fputc('\n', stderr); + va_end(pvar); } - -/*********************************************************************** -*%FUNCTION: sendPacket -*%ARGUMENTS: -* sock -- socket to send to -* pkt -- the packet to transmit -* size -- size of packet (in bytes) -*%RETURNS: -* 0 on success; -1 on failure -*%DESCRIPTION: -* Transmits a packet -***********************************************************************/ -int -sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size) +void +warn(char *fmt, ...) { -#if defined(HAVE_STRUCT_SOCKADDR_LL) - if (send(sock, pkt, size, 0) < 0) { - fatalSys("send (sendPacket)"); - return -1; - } -#else - struct sockaddr sa; - - if (!conn) { - fatal("relay and server not supported on Linux 2.0 kernels"); - } - strcpy(sa.sa_data, conn->ifName); - if (sendto(sock, pkt, size, 0, &sa, sizeof(sa)) < 0) { - fatalSys("sendto (sendPacket)"); - return -1; - } -#endif - return 0; + va_list pvar; + va_start(pvar, fmt); + vfprintf(stderr, fmt, pvar); + fputc('\n', stderr); + va_end(pvar); } -/*********************************************************************** -*%FUNCTION: receivePacket -*%ARGUMENTS: -* sock -- socket to read from -* pkt -- place to store the received packet -* size -- set to size of packet in bytes -*%RETURNS: -* >= 0 if all OK; < 0 if error -*%DESCRIPTION: -* Receives a packet -***********************************************************************/ -int -receivePacket(int sock, PPPoEPacket *pkt, int *size) +void +info(char *fmt, ...) { - if ((*size = recv(sock, pkt, sizeof(PPPoEPacket), 0)) < 0) { - fatalSys("recv (receivePacket)"); - return -1; - } - return 0; + va_list pvar; + va_start(pvar, fmt); + vprintf(fmt, pvar); + putchar('\n'); + va_end(pvar); } -/********************************************************************** -*%FUNCTION: parsePacket -*%ARGUMENTS: -* packet -- the PPPoE discovery packet to parse -* func -- function called for each tag in the packet -* extra -- an opaque data pointer supplied to parsing function -*%RETURNS: -* 0 if everything went well; -1 if there was an error -*%DESCRIPTION: -* Parses a PPPoE discovery packet, calling "func" for each tag in the packet. -* "func" is passed the additional argument "extra". -***********************************************************************/ -int -parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra) +void +init_pr_log(const char *prefix, int level) { - UINT16_t len = ntohs(packet->length); - unsigned char *curTag; - UINT16_t tagType, tagLen; - - if (PPPOE_VER(packet->vertype) != 1) { - fprintf(stderr, "Invalid PPPoE version (%d)\n", - PPPOE_VER(packet->vertype)); - return -1; - } - if (PPPOE_TYPE(packet->vertype) != 1) { - fprintf(stderr, "Invalid PPPoE type (%d)\n", - PPPOE_TYPE(packet->vertype)); - return -1; - } - - /* Do some sanity checks on packet */ - if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */ - fprintf(stderr, "Invalid PPPoE packet length (%u)\n", len); - return -1; - } - - /* Step through the tags */ - curTag = packet->payload; - while(curTag - packet->payload < len) { - /* Alignment is not guaranteed, so do this by hand... */ - tagType = (curTag[0] << 8) + curTag[1]; - tagLen = (curTag[2] << 8) + curTag[3]; - if (tagType == TAG_END_OF_LIST) { - return 0; - } - if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) { - fprintf(stderr, "Invalid PPPoE tag length (%u)\n", tagLen); - return -1; - } - func(tagType, tagLen, curTag+TAG_HDR_SIZE, extra); - curTag = curTag + TAG_HDR_SIZE + tagLen; - } - return 0; } -/********************************************************************** -*%FUNCTION: parseForHostUniq -*%ARGUMENTS: -* type -- tag type -* len -- tag length -* data -- tag data. -* extra -- user-supplied pointer. This is assumed to be a pointer to int. -*%RETURNS: -* Nothing -*%DESCRIPTION: -* If a HostUnique tag is found which matches our PID, sets *extra to 1. -***********************************************************************/ void -parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data, - void *extra) +end_pr_log(void) { - PPPoETag *tag = extra; - - if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) - tag->length = memcmp(data, tag->payload, len); + fflush(debugFile); } -/********************************************************************** -*%FUNCTION: packetIsForMe -*%ARGUMENTS: -* conn -- PPPoE connection info -* packet -- a received PPPoE packet -*%RETURNS: -* 1 if packet is for this PPPoE daemon; 0 otherwise. -*%DESCRIPTION: -* If we are using the Host-Unique tag, verifies that packet contains -* our unique identifier. -***********************************************************************/ -int -packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet) +void +pr_log(void *arg, char *fmt, ...) { - 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->hostUniq.length) return 1; - - parsePacket(packet, parseForHostUniq, &hostUniq); - return !hostUniq.length; + va_list ap; + va_start(ap, fmt); + vfprintf(debugFile, fmt, ap); + va_end(ap); } -/********************************************************************** -*%FUNCTION: parsePADOTags -*%ARGUMENTS: -* type -- tag type -* len -- tag length -* data -- tag data -* extra -- extra user data. Should point to a PacketCriteria structure -* which gets filled in according to selected AC name and service -* name. -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Picks interesting tags out of a PADO packet -***********************************************************************/ -void -parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, - void *extra) +size_t +strlcpy(char *dest, const char *src, size_t len) { - struct PacketCriteria *pc = (struct PacketCriteria *) extra; - PPPoEConnection *conn = pc->conn; - int i; - - switch(type) { - case TAG_AC_NAME: - pc->seenACName = 1; - if (conn->printACNames) { - printf("Access-Concentrator: %.*s\n", (int) len, data); - } - if (conn->acName && len == strlen(conn->acName) && - !strncmp((char *) data, conn->acName, len)) { - pc->acNameOK = 1; - } - break; - case TAG_SERVICE_NAME: - pc->seenServiceName = 1; - if (conn->printACNames && len > 0) { - printf(" Service-Name: %.*s\n", (int) len, data); - } - if (conn->serviceName && len == strlen(conn->serviceName) && - !strncmp((char *) data, conn->serviceName, len)) { - pc->serviceNameOK = 1; - } - break; - case TAG_AC_COOKIE: - if (conn->printACNames) { - printf("Got a cookie:"); - /* Print first 20 bytes of cookie */ - for (i=0; i<len && i < 20; i++) { - printf(" %02x", (unsigned) data[i]); - } - if (i < len) printf("..."); - printf("\n"); - } - conn->cookie.type = htons(type); - conn->cookie.length = htons(len); - memcpy(conn->cookie.payload, data, len); - break; - case TAG_RELAY_SESSION_ID: - if (conn->printACNames) { - printf("Got a Relay-ID:"); - /* Print first 20 bytes of relay ID */ - for (i=0; i<len && i < 20; i++) { - printf(" %02x", (unsigned) data[i]); - } - if (i < len) printf("..."); - printf("\n"); - } - conn->relayId.type = htons(type); - conn->relayId.length = htons(len); - memcpy(conn->relayId.payload, data, len); - break; - case TAG_SERVICE_NAME_ERROR: - if (conn->printACNames) { - printf("Got a Service-Name-Error tag: %.*s\n", (int) len, data); - } - break; - case TAG_AC_SYSTEM_ERROR: - if (conn->printACNames) { - printf("Got a System-Error tag: %.*s\n", (int) len, data); + size_t ret = strlen(src); + + if (len != 0) { + if (ret < len) + strcpy(dest, src); + else { + strncpy(dest, src, len - 1); + dest[len-1] = 0; } - break; - case TAG_GENERIC_ERROR: - if (conn->printACNames) { - printf("Got a Generic-Error tag: %.*s\n", (int) len, data); - } - break; } + return ret; } -/*********************************************************************** -*%FUNCTION: sendPADI -*%ARGUMENTS: -* conn -- PPPoEConnection structure -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Sends a PADI packet -***********************************************************************/ -void -sendPADI(PPPoEConnection *conn) +static char * +xstrdup(const char *s) { - PPPoEPacket packet; - unsigned char *cursor = packet.payload; - PPPoETag *svc = (PPPoETag *) (&packet.payload); - UINT16_t namelen = 0; - UINT16_t plen; - - if (conn->serviceName) { - namelen = (UINT16_t) strlen(conn->serviceName); - } - plen = TAG_HDR_SIZE + namelen; - CHECK_ROOM(cursor, packet.payload, plen); - - /* Set destination to Ethernet broadcast address */ - memset(packet.ethHdr.h_dest, 0xFF, ETH_ALEN); - memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); - - packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); - packet.vertype = PPPOE_VER_TYPE(1, 1); - packet.code = CODE_PADI; - packet.session = 0; - - svc->type = TAG_SERVICE_NAME; - svc->length = htons(namelen); - CHECK_ROOM(cursor, packet.payload, namelen+TAG_HDR_SIZE); - - if (conn->serviceName) { - memcpy(svc->payload, conn->serviceName, strlen(conn->serviceName)); - } - cursor += namelen + TAG_HDR_SIZE; - - /* If we're using Host-Uniq, copy it over */ - 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); - - sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); - if (conn->debugFile) { - dumpPacket(conn->debugFile, &packet, "SENT"); - fprintf(conn->debugFile, "\n"); - fflush(conn->debugFile); + char *ret = strdup(s); + if (!ret) { + perror("strdup"); + exit(1); } + return ret; } -/********************************************************************** -*%FUNCTION: waitForPADO -*%ARGUMENTS: -* conn -- PPPoEConnection structure -* timeout -- how long to wait (in seconds) -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Waits for a PADO packet and copies useful information -***********************************************************************/ -void -waitForPADO(PPPoEConnection *conn, int timeout) +int +get_time(struct timeval *tv) { - fd_set readable; - int r; - struct timeval tv; - PPPoEPacket packet; - int len; - - struct PacketCriteria pc; - pc.conn = conn; - pc.acNameOK = (conn->acName) ? 0 : 1; - pc.serviceNameOK = (conn->serviceName) ? 0 : 1; - pc.seenACName = 0; - pc.seenServiceName = 0; - conn->error = 0; - - do { - if (BPF_BUFFER_IS_EMPTY) { - tv.tv_sec = timeout; - tv.tv_usec = 0; - - FD_ZERO(&readable); - FD_SET(conn->discoverySocket, &readable); - - while(1) { - r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); - if (r >= 0 || errno != EINTR) break; - } - if (r < 0) { - perror("select (waitForPADO)"); - return; - } - if (r == 0) return; /* Timed out */ - } - - /* Get the packet */ - receivePacket(conn->discoverySocket, &packet, &len); - - /* Check length */ - if (ntohs(packet.length) + HDR_SIZE > len) { - fprintf(stderr, "Bogus PPPoE length field (%u)\n", - (unsigned int) ntohs(packet.length)); - continue; - } - -#ifdef USE_BPF - /* If it's not a Discovery packet, loop again */ - if (etherType(&packet) != Eth_PPPOE_Discovery) continue; -#endif - - if (conn->debugFile) { - dumpPacket(conn->debugFile, &packet, "RCVD"); - fprintf(conn->debugFile, "\n"); - fflush(conn->debugFile); - } - /* If it's not for us, loop again */ - if (!packetIsForMe(conn, &packet)) continue; - - if (packet.code == CODE_PADO) { - if (BROADCAST(packet.ethHdr.h_source)) { - fprintf(stderr, "Ignoring PADO packet from broadcast MAC address\n"); - continue; - } - parsePacket(&packet, parsePADOTags, &pc); - if (conn->error) - return; - if (!pc.seenACName) { - fprintf(stderr, "Ignoring PADO packet with no AC-Name tag\n"); - continue; - } - if (!pc.seenServiceName) { - fprintf(stderr, "Ignoring PADO packet with no Service-Name tag\n"); - continue; - } - conn->numPADOs++; - if (pc.acNameOK && pc.serviceNameOK) { - memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); - if (conn->printACNames) { - printf("AC-Ethernet-Address: %02x:%02x:%02x:%02x:%02x:%02x\n", - (unsigned) conn->peerEth[0], - (unsigned) conn->peerEth[1], - (unsigned) conn->peerEth[2], - (unsigned) conn->peerEth[3], - (unsigned) conn->peerEth[4], - (unsigned) conn->peerEth[5]); - printf("--------------------------------------------------\n"); - continue; - } - conn->discoveryState = STATE_RECEIVED_PADO; - break; - } - } - } while (conn->discoveryState != STATE_RECEIVED_PADO); + return gettimeofday(tv, NULL); } -/********************************************************************** -*%FUNCTION: discovery -*%ARGUMENTS: -* conn -- PPPoE connection info structure -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Performs the PPPoE discovery phase -***********************************************************************/ -void -discovery(PPPoEConnection *conn) +static void +term_handler(int signum) { - int padiAttempts = 0; - int timeout = conn->discoveryTimeout; - - conn->discoverySocket = - openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); - - do { - padiAttempts++; - if (padiAttempts > conn->discoveryAttempts) { - fprintf(stderr, "Timeout waiting for PADO packets\n"); - close(conn->discoverySocket); - conn->discoverySocket = -1; - return; - } - sendPADI(conn); - conn->discoveryState = STATE_SENT_PADI; - waitForPADO(conn, timeout); - } while (!conn->numPADOs); + got_sigterm = 1; } +static void usage(void); + int main(int argc, char *argv[]) { int opt; PPPoEConnection *conn; + signal(SIGINT, term_handler); + signal(SIGTERM, term_handler); + conn = malloc(sizeof(PPPoEConnection)); - if (!conn) - fatalSys("malloc"); + if (!conn) { + perror("malloc"); + exit(1); + } memset(conn, 0, sizeof(PPPoEConnection)); - conn->printACNames = 1; + pppoe_verbose = 1; conn->discoveryTimeout = PADI_TIMEOUT; conn->discoveryAttempts = MAX_PADI_ATTEMPTS; @@ -705,19 +225,21 @@ int main(int argc, char *argv[]) } break; case 'D': - conn->debugFile = fopen(optarg, "w"); - if (!conn->debugFile) { + pppoe_verbose = 2; + debug = 1; + debugFile = fopen(optarg, "w"); + if (!debugFile) { fprintf(stderr, "Could not open %s: %s\n", optarg, strerror(errno)); exit(1); } - fprintf(conn->debugFile, "pppoe-discovery from pppd %s\n", VERSION); + fprintf(debugFile, "pppoe-discovery from pppd %s\n", VERSION); break; case 'I': conn->ifName = xstrdup(optarg); break; case 'Q': - conn->printACNames = 0; + pppoe_verbose = 0; break; case 'V': case 'h': @@ -731,12 +253,17 @@ int main(int argc, char *argv[]) /* default interface name */ if (!conn->ifName) - conn->ifName = strdup("eth0"); + conn->ifName = xstrdup("eth0"); - conn->discoverySocket = -1; conn->sessionSocket = -1; - discovery(conn); + conn->discoverySocket = openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); + if (conn->discoverySocket < 0) { + perror("Cannot create PPPoE discovery socket"); + exit(1); + } + + discovery1(conn); if (!conn->numPADOs) exit(1); @@ -744,31 +271,8 @@ int main(int argc, char *argv[]) exit(0); } -void fatal(char * fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fputc('\n', stderr); - exit(1); -} - -void fatalSys(char const *str) -{ - perror(str); - exit(1); -} - -char *xstrdup(const char *s) -{ - register char *ret = strdup(s); - if (!ret) - fatalSys("strdup"); - return ret; -} - -void usage(void) +static void +usage(void) { fprintf(stderr, "Usage: pppoe-discovery [options]\n"); fprintf(stderr, "Options:\n"); diff --git a/pppd/plugins/pppoe/pppoe.h b/pppd/plugins/pppoe/pppoe.h index 5d96f0c..26e14f5 100644 --- a/pppd/plugins/pppoe/pppoe.h +++ b/pppd/plugins/pppoe/pppoe.h @@ -231,18 +231,17 @@ typedef struct PPPoEConnectionStruct { char *acName; /* Desired AC name, if any */ int synchronous; /* Use synchronous PPP */ 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 */ PPPoETag cookie; /* We have to send this if we get it */ PPPoETag relayId; /* Ditto */ int error; /* Error packet received */ - int debug; /* Set to log packets sent and received */ int discoveryTimeout; /* Timeout for discovery packets */ int discoveryAttempts; /* Number of discovery attempts */ int seenMaxPayload; - int mtu; /* Stored MTU */ - int mru; /* Stored MRU */ + int storedmtu; /* Stored MTU */ + int storedmru; /* Stored MRU */ + int mtu; + int mru; } PPPoEConnection; /* Structure used to determine acceptable PADO or PADS packet */ @@ -259,9 +258,6 @@ UINT16_t etherType(PPPoEPacket *packet); int openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr); int sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size); int receivePacket(int sock, PPPoEPacket *pkt, int *size); -void fatalSys(char const *str); -void dumpPacket(FILE *fp, PPPoEPacket *packet, char const *dir); -void dumpHex(FILE *fp, unsigned char const *buf, int len); int parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra); void parseLogErrs(UINT16_t typ, UINT16_t len, unsigned char *data, void *xtra); void syncReadFromPPP(PPPoEConnection *conn, PPPoEPacket *packet); @@ -276,10 +272,12 @@ void initPPP(void); void clampMSS(PPPoEPacket *packet, char const *dir, int clampMss); UINT16_t computeTCPChecksum(unsigned char *ipHdr, unsigned char *tcpHdr); UINT16_t pppFCS16(UINT16_t fcs, unsigned char *cp, int len); -void discovery(PPPoEConnection *conn); +void discovery1(PPPoEConnection *conn); +void discovery2(PPPoEConnection *conn); unsigned char *findTag(PPPoEPacket *packet, UINT16_t tagType, PPPoETag *tag); +extern int pppoe_verbose; void pppoe_printpkt(PPPoEPacket *packet, void (*printer)(void *, char *, ...), void *arg); void pppoe_log_packet(const char *prefix, PPPoEPacket *packet); diff --git a/pppd/pppd.8 b/pppd/pppd.8 index 7417a36..b31594a 100644 --- a/pppd/pppd.8 +++ b/pppd/pppd.8 @@ -1294,8 +1294,9 @@ Attach to existing PPPoE session. For backward compatibility also \fBrp_pppoe_sess\fP option name is supported. .TP .B pppoe-verbose \fIn -Be verbose about discovered access concentrators. For backward -compatibility also \fBrp_pppoe_verbose\fP option name is supported. +Be verbose about discovered access concentrators. When set to 2 or bigger +value then dump also discovery packets. For backward compatibility also +\fBrp_pppoe_verbose\fP option name is supported. .TP .B pppoe-mac \fImacaddr Connect to specified MAC address. |