X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fplugins%2Frp-pppoe%2Fpppoe-discovery.c;h=8b2e946f4d711d516e6f43fc73dbd45405c8b7a9;hp=55037dffb02322e6d92cf099270b5e41739f46b4;hb=c9d9dbfb8459b528ab56bd1cf0c41460801bbfdf;hpb=a3f379befd11934466271aaca76b2809ae8595d0 diff --git a/pppd/plugins/rp-pppoe/pppoe-discovery.c b/pppd/plugins/rp-pppoe/pppoe-discovery.c index 55037df..8b2e946 100644 --- a/pppd/plugins/rp-pppoe/pppoe-discovery.c +++ b/pppd/plugins/rp-pppoe/pppoe-discovery.c @@ -181,7 +181,8 @@ openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) sa.sll_family = AF_PACKET; sa.sll_protocol = htons(type); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + 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"); } @@ -356,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; @@ -387,7 +388,9 @@ parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, switch(type) { case TAG_AC_NAME: pc->seenACName = 1; - printf("Access-Concentrator: %.*s\n", (int) len, data); + 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; @@ -395,7 +398,7 @@ parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, break; case TAG_SERVICE_NAME: pc->seenServiceName = 1; - if (len > 0) { + if (conn->printACNames && len > 0) { printf(" Service-Name: %.*s\n", (int) len, data); } if (conn->serviceName && len == strlen(conn->serviceName) && @@ -404,37 +407,47 @@ parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, } break; case TAG_AC_COOKIE: - printf("Got a cookie:"); - /* Print first 20 bytes of cookie */ - for (i=0; iprintACNames) { + printf("Got a cookie:"); + /* Print first 20 bytes of cookie */ + for (i=0; icookie.type = htons(type); conn->cookie.length = htons(len); memcpy(conn->cookie.payload, data, len); break; case TAG_RELAY_SESSION_ID: - printf("Got a Relay-ID:"); - /* Print first 20 bytes of relay ID */ - for (i=0; iprintACNames) { + printf("Got a Relay-ID:"); + /* Print first 20 bytes of relay ID */ + for (i=0; irelayId.type = htons(type); conn->relayId.length = htons(len); memcpy(conn->relayId.payload, data, len); break; case TAG_SERVICE_NAME_ERROR: - printf("Got a Service-Name-Error tag: %.*s\n", (int) len, data); + if (conn->printACNames) { + printf("Got a Service-Name-Error tag: %.*s\n", (int) len, data); + } break; case TAG_AC_SYSTEM_ERROR: - printf("Got a System-Error tag: %.*s\n", (int) len, data); + if (conn->printACNames) { + printf("Got a System-Error tag: %.*s\n", (int) len, data); + } break; case TAG_GENERIC_ERROR: - printf("Got a Generic-Error tag: %.*s\n", (int) len, data); + if (conn->printACNames) { + printf("Got a Generic-Error tag: %.*s\n", (int) len, data); + } break; } } @@ -482,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); @@ -590,7 +599,6 @@ waitForPADO(PPPoEConnection *conn, int timeout) continue; } conn->numPADOs++; - printf("--------------------------------------------------\n"); if (pc.acNameOK && pc.serviceNameOK) { memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); if (conn->printACNames) { @@ -601,6 +609,7 @@ waitForPADO(PPPoEConnection *conn, int timeout) (unsigned) conn->peerEth[3], (unsigned) conn->peerEth[4], (unsigned) conn->peerEth[5]); + printf("--------------------------------------------------\n"); continue; } conn->discoveryState = STATE_RECEIVED_PADO; @@ -623,14 +632,14 @@ void discovery(PPPoEConnection *conn) { int padiAttempts = 0; - int timeout = PADI_TIMEOUT; + int timeout = conn->discoveryTimeout; conn->discoverySocket = openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); do { padiAttempts++; - if (padiAttempts > MAX_PADI_ATTEMPTS) { + if (padiAttempts > conn->discoveryAttempts) { fprintf(stderr, "Timeout waiting for PADO packets\n"); close(conn->discoverySocket); conn->discoverySocket = -1; @@ -653,7 +662,11 @@ int main(int argc, char *argv[]) memset(conn, 0, sizeof(PPPoEConnection)); - while ((opt = getopt(argc, argv, "I:D:VUAS:C:h")) > 0) { + conn->printACNames = 1; + conn->discoveryTimeout = PADI_TIMEOUT; + conn->discoveryAttempts = MAX_PADI_ATTEMPTS; + + while ((opt = getopt(argc, argv, "I:D:VUQS:C:W:t:a:h")) > 0) { switch(opt) { case 'S': conn->serviceName = xstrdup(optarg); @@ -661,8 +674,44 @@ int main(int argc, char *argv[]) case 'C': conn->acName = xstrdup(optarg); break; + case 't': + if (sscanf(optarg, "%d", &conn->discoveryTimeout) != 1) { + fprintf(stderr, "Illegal argument to -t: Should be -t timeout\n"); + exit(EXIT_FAILURE); + } + if (conn->discoveryTimeout < 1) { + conn->discoveryTimeout = 1; + } + break; + case 'a': + if (sscanf(optarg, "%d", &conn->discoveryAttempts) != 1) { + fprintf(stderr, "Illegal argument to -a: Should be -a attempts\n"); + exit(EXIT_FAILURE); + } + if (conn->discoveryAttempts < 1) { + conn->discoveryAttempts = 1; + } + 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"); @@ -676,8 +725,8 @@ int main(int argc, char *argv[]) case 'I': conn->ifName = xstrdup(optarg); break; - case 'A': - /* this is the default */ + case 'Q': + conn->printACNames = 0; break; case 'V': case 'h': @@ -695,10 +744,13 @@ int main(int argc, char *argv[]) conn->discoverySocket = -1; conn->sessionSocket = -1; - conn->printACNames = 1; discovery(conn); - exit(0); + + if (!conn->numPADOs) + exit(1); + else + exit(0); } void rp_fatal(char const *str) @@ -729,5 +781,18 @@ char *xstrdup(const char *s) void usage(void) { fprintf(stderr, "Usage: pppoe-discovery [options]\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -I if_name -- Specify interface (default eth0)\n"); + fprintf(stderr, " -D filename -- Log debugging information in filename.\n"); + fprintf(stderr, + " -t timeout -- Initial timeout for discovery packets in seconds\n" + " -a attempts -- Number of discovery attempts\n" + " -V -- Print version and exit.\n" + " -Q -- Quit Mode: Do not print access concentrator names\n" + " -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"); }