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;
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);
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));
conn->printACNames = 1;
+ conn->discoveryTimeout = PADI_TIMEOUT;
+ conn->discoveryAttempts = MAX_PADI_ATTEMPTS;
- while ((opt = getopt(argc, argv, "I:D:VUQS:C:h")) > 0) {
+ 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");
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");
}