]> git.ozlabs.org Git - ppp.git/blob - pppd/plugins/pppoe/pppoe-discovery.c
pppd: constify log format strings. (#462)
[ppp.git] / pppd / plugins / pppoe / pppoe-discovery.c
1 /*
2  * Perform PPPoE discovery
3  *
4  * Copyright (C) 2000-2001 by Roaring Penguin Software Inc.
5  * Copyright (C) 2004 Marco d'Itri <md@linux.it>
6  *
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.
9  *
10  */
11
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15
16 #include <stdarg.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <errno.h>
21 #include <string.h>
22 #include <time.h>
23 #include <signal.h>
24 #include <sys/time.h>
25 #include <stdbool.h>
26 #include <stdint.h>
27
28 #include "pppoe.h"
29
30 int debug;
31 int got_sigterm;
32 int pppoe_verbose;
33 static FILE *debugFile;
34
35 void
36 fatal(const char *fmt, ...)
37 {
38     va_list pvar;
39     va_start(pvar, fmt);
40     vfprintf(stderr, fmt, pvar);
41     va_end(pvar);
42     fputc('\n', stderr);
43     exit(1);
44 }
45
46 void
47 error(const char *fmt, ...)
48 {
49     va_list pvar;
50     va_start(pvar, fmt);
51     vfprintf(stderr, fmt, pvar);
52     fputc('\n', stderr);
53     va_end(pvar);
54 }
55
56 void
57 warn(const char *fmt, ...)
58 {
59     va_list pvar;
60     va_start(pvar, fmt);
61     vfprintf(stderr, fmt, pvar);
62     fputc('\n', stderr);
63     va_end(pvar);
64 }
65
66 void
67 info(const char *fmt, ...)
68 {
69     va_list pvar;
70     va_start(pvar, fmt);
71     vprintf(fmt, pvar);
72     putchar('\n');
73     va_end(pvar);
74 }
75
76 void
77 init_pr_log(const char *prefix, int level)
78 {
79 }
80
81 void
82 end_pr_log(void)
83 {
84     fflush(debugFile);
85 }
86
87 void
88 pr_log(void *arg, char *fmt, ...)
89 {
90     va_list ap;
91     va_start(ap, fmt);
92     vfprintf(debugFile, fmt, ap);
93     va_end(ap);
94 }
95
96 size_t
97 strlcpy(char *dest, const char *src, size_t len)
98 {
99     size_t ret = strlen(src);
100
101     if (len != 0) {
102         if (ret < len)
103             strcpy(dest, src);
104         else {
105             strncpy(dest, src, len - 1);
106             dest[len-1] = 0;
107         }
108     }
109     return ret;
110 }
111
112 static char *
113 xstrdup(const char *s)
114 {
115     char *ret = strdup(s);
116     if (!ret) {
117         perror("strdup");
118         exit(1);
119     }
120     return ret;
121 }
122
123 int
124 get_time(struct timeval *tv)
125 {
126     return gettimeofday(tv, NULL);
127 }
128
129 int signaled(int signal) {
130     if (signal == SIGTERM)
131         return got_sigterm;
132     return 0;
133 }
134
135 bool debug_on()
136 {
137     return !!debug;
138 }
139
140 static void
141 term_handler(int signum)
142 {
143     got_sigterm = 1;
144 }
145
146 static void usage(void);
147
148 int main(int argc, char *argv[])
149 {
150     int opt;
151     PPPoEConnection *conn;
152
153     signal(SIGINT, term_handler);
154     signal(SIGTERM, term_handler);
155
156     conn = malloc(sizeof(PPPoEConnection));
157     if (!conn) {
158         perror("malloc");
159         exit(1);
160     }
161
162     memset(conn, 0, sizeof(PPPoEConnection));
163
164     pppoe_verbose = 1;
165     conn->discoveryTimeout = PADI_TIMEOUT;
166     conn->discoveryAttempts = MAX_PADI_ATTEMPTS;
167
168     while ((opt = getopt(argc, argv, "I:D:VUQS:C:W:t:a:h")) > 0) {
169         switch(opt) {
170         case 'S':
171             conn->serviceName = xstrdup(optarg);
172             break;
173         case 'C':
174             conn->acName = xstrdup(optarg);
175             break;
176         case 't':
177             if (sscanf(optarg, "%d", &conn->discoveryTimeout) != 1) {
178                 fprintf(stderr, "Illegal argument to -t: Should be -t timeout\n");
179                 exit(EXIT_FAILURE);
180             }
181             if (conn->discoveryTimeout < 1) {
182                 conn->discoveryTimeout = 1;
183             }
184             break;
185         case 'a':
186             if (sscanf(optarg, "%d", &conn->discoveryAttempts) != 1) {
187                 fprintf(stderr, "Illegal argument to -a: Should be -a attempts\n");
188                 exit(EXIT_FAILURE);
189             }
190             if (conn->discoveryAttempts < 1) {
191                 conn->discoveryAttempts = 1;
192             }
193             break;
194         case 'U':
195             if(conn->hostUniq.length) {
196                 fprintf(stderr, "-U and -W are mutually exclusive\n");
197                 exit(EXIT_FAILURE);
198             } else {
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));
203             }
204             break;
205         case 'W':
206             if(conn->hostUniq.length) {
207                 fprintf(stderr, "-U and -W are mutually exclusive\n");
208                 exit(EXIT_FAILURE);
209             }
210             if (!parseHostUniq(optarg, &conn->hostUniq)) {
211                 fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg);
212                 exit(EXIT_FAILURE);
213             }
214             break;
215         case 'D':
216             pppoe_verbose = 2;
217             debug = 1;
218             debugFile = fopen(optarg, "w");
219             if (!debugFile) {
220                 fprintf(stderr, "Could not open %s: %s\n",
221                         optarg, strerror(errno));
222                 exit(1);
223             }
224             fprintf(debugFile, "pppoe-discovery from pppd %s\n", PPPD_VERSION);
225             break;
226         case 'I':
227             conn->ifName = xstrdup(optarg);
228             break;
229         case 'Q':
230             pppoe_verbose = 0;
231             break;
232         case 'V':
233         case 'h':
234             usage();
235             exit(0);
236         default:
237             usage();
238             exit(1);
239         }
240     }
241
242     if (optind != argc) {
243         fprintf(stderr, "%s: extra argument '%s'\n", argv[0], argv[optind]);
244         usage();
245         exit(EXIT_FAILURE);
246     }
247
248     if (!conn->ifName) {
249         fprintf(stderr, "Interface was not specified\n");
250         exit(EXIT_FAILURE);
251     }
252
253     conn->sessionSocket = -1;
254
255     conn->discoverySocket = openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth);
256     if (conn->discoverySocket < 0) {
257         perror("Cannot create PPPoE discovery socket");
258         exit(1);
259     }
260
261     discovery1(conn);
262
263     if (!conn->numPADOs)
264         exit(1);
265     else
266         exit(0);
267 }
268
269 static void
270 usage(void)
271 {
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");
276     fprintf(stderr,
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");
287 }