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.
33 static FILE *debugFile;
36 fatal(const char *fmt, ...)
40 vfprintf(stderr, fmt, pvar);
47 error(const char *fmt, ...)
51 vfprintf(stderr, fmt, pvar);
57 warn(const char *fmt, ...)
61 vfprintf(stderr, fmt, pvar);
67 info(const char *fmt, ...)
77 init_pr_log(const char *prefix, int level)
88 pr_log(void *arg, char *fmt, ...)
92 vfprintf(debugFile, fmt, ap);
97 strlcpy(char *dest, const char *src, size_t len)
99 size_t ret = strlen(src);
105 strncpy(dest, src, len - 1);
113 xstrdup(const char *s)
115 char *ret = strdup(s);
124 get_time(struct timeval *tv)
126 return gettimeofday(tv, NULL);
129 int signaled(int signal) {
130 if (signal == SIGTERM)
141 term_handler(int signum)
146 static void usage(void);
148 int main(int argc, char *argv[])
151 PPPoEConnection *conn;
153 signal(SIGINT, term_handler);
154 signal(SIGTERM, term_handler);
156 conn = malloc(sizeof(PPPoEConnection));
162 memset(conn, 0, sizeof(PPPoEConnection));
165 conn->discoveryTimeout = PADI_TIMEOUT;
166 conn->discoveryAttempts = MAX_PADI_ATTEMPTS;
168 while ((opt = getopt(argc, argv, "I:D:VUQS:C:W:t:a:h")) > 0) {
171 conn->serviceName = xstrdup(optarg);
174 conn->acName = xstrdup(optarg);
177 if (sscanf(optarg, "%d", &conn->discoveryTimeout) != 1) {
178 fprintf(stderr, "Illegal argument to -t: Should be -t timeout\n");
181 if (conn->discoveryTimeout < 1) {
182 conn->discoveryTimeout = 1;
186 if (sscanf(optarg, "%d", &conn->discoveryAttempts) != 1) {
187 fprintf(stderr, "Illegal argument to -a: Should be -a attempts\n");
190 if (conn->discoveryAttempts < 1) {
191 conn->discoveryAttempts = 1;
195 if(conn->hostUniq.length) {
196 fprintf(stderr, "-U and -W are mutually exclusive\n");
199 pid_t pid = getpid();
200 conn->hostUniq.type = htons(TAG_HOST_UNIQ);
201 conn->hostUniq.length = htons(sizeof(pid));
202 memcpy(conn->hostUniq.payload, &pid, sizeof(pid));
206 if(conn->hostUniq.length) {
207 fprintf(stderr, "-U and -W are mutually exclusive\n");
210 if (!parseHostUniq(optarg, &conn->hostUniq)) {
211 fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg);
218 debugFile = fopen(optarg, "w");
220 fprintf(stderr, "Could not open %s: %s\n",
221 optarg, strerror(errno));
224 fprintf(debugFile, "pppoe-discovery from pppd %s\n", PPPD_VERSION);
227 conn->ifName = xstrdup(optarg);
242 if (optind != argc) {
243 fprintf(stderr, "%s: extra argument '%s'\n", argv[0], argv[optind]);
249 fprintf(stderr, "Interface was not specified\n");
253 conn->sessionSocket = -1;
255 conn->discoverySocket = openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth);
256 if (conn->discoverySocket < 0) {
257 perror("Cannot create PPPoE discovery socket");
272 fprintf(stderr, "Usage: pppoe-discovery [options]\n");
273 fprintf(stderr, "Options:\n");
274 fprintf(stderr, " -I if_name -- Specify interface (mandatory option)\n");
275 fprintf(stderr, " -D filename -- Log debugging information in filename.\n");
277 " -t timeout -- Initial timeout for discovery packets in seconds\n"
278 " -a attempts -- Number of discovery attempts\n"
279 " -V -- Print version and exit.\n"
280 " -Q -- Quit Mode: Do not print access concentrator names\n"
281 " -S name -- Set desired service name.\n"
282 " -C name -- Set desired access concentrator name.\n"
283 " -U -- Use Host-Unique to allow multiple PPPoE sessions.\n"
284 " -W hexvalue -- Set the Host-Unique to the supplied hex string.\n"
285 " -h -- Print usage information.\n");
286 fprintf(stderr, "\npppoe-discovery from pppd " PPPD_VERSION "\n");