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");
}
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;
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;
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) &&
}
break;
case TAG_AC_COOKIE:
- printf("Got a cookie:");
- /* Print first 20 bytes of cookie */
- for (i=0; i<len && i < 20; i++) {
- printf(" %02x", (unsigned) data[i]);
+ 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");
}
- 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:
- 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 (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");
}
- 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:
- 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;
}
}
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);
continue;
}
conn->numPADOs++;
- printf("--------------------------------------------------\n");
if (pc.acNameOK && pc.serviceNameOK) {
memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN);
if (conn->printACNames) {
(unsigned) conn->peerEth[3],
(unsigned) conn->peerEth[4],
(unsigned) conn->peerEth[5]);
+ printf("--------------------------------------------------\n");
continue;
}
conn->discoveryState = STATE_RECEIVED_PADO;
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;
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);
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");
case 'I':
conn->ifName = xstrdup(optarg);
break;
- case 'A':
- /* this is the default */
+ case 'Q':
+ conn->printACNames = 0;
break;
case 'V':
case 'h':
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)
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");
}