2 * Perform PPPoE discovery
4 * Copyright (C) 2000-2001 by Roaring Penguin Software Inc.
5 * Copyright (C) 2004 Marco d'Itri <md@linux.it>
7 * This program may be distributed according to the terms of the GNU
8 * General Public License, version 2 or (at your option) any later version.
27 #ifdef HAVE_NETPACKET_PACKET_H
28 #include <netpacket/packet.h>
29 #elif defined(HAVE_LINUX_IF_PACKET_H)
30 #include <linux/if_packet.h>
33 #ifdef HAVE_ASM_TYPES_H
34 #include <asm/types.h>
37 #ifdef HAVE_SYS_IOCTL_H
38 #include <sys/ioctl.h>
45 #ifdef HAVE_NET_IF_ARP_H
46 #include <net/if_arp.h>
52 static FILE *debugFile;
59 vfprintf(stderr, fmt, pvar);
70 vfprintf(stderr, fmt, pvar);
80 vfprintf(stderr, fmt, pvar);
96 init_pr_log(const char *prefix, int level)
107 pr_log(void *arg, char *fmt, ...)
111 vfprintf(debugFile, fmt, ap);
116 strlcpy(char *dest, const char *src, size_t len)
118 size_t ret = strlen(src);
124 strncpy(dest, src, len - 1);
132 xstrdup(const char *s)
134 char *ret = strdup(s);
143 get_time(struct timeval *tv)
145 return gettimeofday(tv, NULL);
149 term_handler(int signum)
154 static void usage(void);
156 int main(int argc, char *argv[])
159 PPPoEConnection *conn;
161 signal(SIGINT, term_handler);
162 signal(SIGTERM, term_handler);
164 conn = malloc(sizeof(PPPoEConnection));
170 memset(conn, 0, sizeof(PPPoEConnection));
173 conn->discoveryTimeout = PADI_TIMEOUT;
174 conn->discoveryAttempts = MAX_PADI_ATTEMPTS;
176 while ((opt = getopt(argc, argv, "I:D:VUQS:C:W:t:a:h")) > 0) {
179 conn->serviceName = xstrdup(optarg);
182 conn->acName = xstrdup(optarg);
185 if (sscanf(optarg, "%d", &conn->discoveryTimeout) != 1) {
186 fprintf(stderr, "Illegal argument to -t: Should be -t timeout\n");
189 if (conn->discoveryTimeout < 1) {
190 conn->discoveryTimeout = 1;
194 if (sscanf(optarg, "%d", &conn->discoveryAttempts) != 1) {
195 fprintf(stderr, "Illegal argument to -a: Should be -a attempts\n");
198 if (conn->discoveryAttempts < 1) {
199 conn->discoveryAttempts = 1;
203 if(conn->hostUniq.length) {
204 fprintf(stderr, "-U and -W are mutually exclusive\n");
207 pid_t pid = getpid();
208 conn->hostUniq.type = htons(TAG_HOST_UNIQ);
209 conn->hostUniq.length = htons(sizeof(pid));
210 memcpy(conn->hostUniq.payload, &pid, sizeof(pid));
214 if(conn->hostUniq.length) {
215 fprintf(stderr, "-U and -W are mutually exclusive\n");
218 if (!parseHostUniq(optarg, &conn->hostUniq)) {
219 fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg);
226 debugFile = fopen(optarg, "w");
228 fprintf(stderr, "Could not open %s: %s\n",
229 optarg, strerror(errno));
232 fprintf(debugFile, "pppoe-discovery from pppd %s\n", VERSION);
235 conn->ifName = xstrdup(optarg);
250 /* default interface name */
252 conn->ifName = xstrdup("eth0");
254 conn->sessionSocket = -1;
256 conn->discoverySocket = openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth);
257 if (conn->discoverySocket < 0) {
258 perror("Cannot create PPPoE discovery socket");
273 fprintf(stderr, "Usage: pppoe-discovery [options]\n");
274 fprintf(stderr, "Options:\n");
275 fprintf(stderr, " -I if_name -- Specify interface (default eth0)\n");
276 fprintf(stderr, " -D filename -- Log debugging information in filename.\n");
278 " -t timeout -- Initial timeout for discovery packets in seconds\n"
279 " -a attempts -- Number of discovery attempts\n"
280 " -V -- Print version and exit.\n"
281 " -Q -- Quit Mode: Do not print access concentrator names\n"
282 " -S name -- Set desired service name.\n"
283 " -C name -- Set desired access concentrator name.\n"
284 " -U -- Use Host-Unique to allow multiple PPPoE sessions.\n"
285 " -W hexvalue -- Set the Host-Unique to the supplied hex string.\n"
286 " -h -- Print usage information.\n");
287 fprintf(stderr, "\npppoe-discovery from pppd " VERSION "\n");