pppoe plugin stuff - Michal Ostrowski's version, lightly hacked
[ppp.git] / pppd / plugins / pppoe / pppoed.c
1 /* PPPoE support library "libpppoe"
2  *
3  * Copyright 2000 Jamal Hadi Salim <hadi@cyberus.ca>
4  *
5  *  This program is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU General Public License
7  *  as published by the Free Software Foundation; either version
8  *  2 of the License, or (at your option) any later version.
9  */
10
11 #include "pppoe.h"
12
13 int detached=1;
14 void
15 sigproc (int src)
16 {
17     int i;
18     fprintf (stderr,"Received signal %d", src);
19 }
20
21 void
22 sigchild (int src)
23 {
24     pid_t pid;
25     int status;
26     int i;
27     pid = waitpid (-1, &status, WNOHANG);
28     
29     if (!detached)
30         fprintf (stderr,"Child received signal %d PID %d, status %d", src, pid, status);
31     if (pid < 1) {
32         return;
33     }
34 }
35
36 void
37 print_help ()
38 {
39     
40     fprintf (stdout,"\npppoe version %d.%d build %d", VERSION_MAJOR, VERSION_MINOR,
41              VERSION_DATE);
42     fprintf (stdout,"\nrecognized options are:");
43     fprintf (stdout,"\n -I <interface> : overrides the default interface of eth0");
44     fprintf (stdout,"\n -S : starts pppoed in server mode");
45     fprintf (stdout,"\n -R <num_retries>: forces pppoed to be restarted num_retries");
46     fprintf (stdout,"\n                   should the other end be detected to be dead.");
47     fprintf (stdout,"\n                   Needs lcp_echo. Read the INSTALL file instructions");
48     fprintf (stdout,"\n -F <filename> : specifies additional ppp options file");
49     fprintf (stdout,"\n -C <filename> : ppp options file in /etc/ppp/peers/");
50     fprintf (stdout,"\n -d <level> : sets debug level");
51     fprintf (stdout,"\n -D : prevents pppoed from detaching itself and running in the background");
52     fprintf (stdout,"\n -P <path to pppd> : selects a different pppd. Defaults to " _PATH_PPPD);
53     fprintf (stdout,"\n -A <AC name> to select a specific AC by name");
54     fprintf (stdout,"\n -E <AC service name> to select a specific AC service by name");
55     fprintf (stdout,"\n -G Do service discovery only");
56     fprintf (stdout,"\n -H Do service discovery and connection (no pppd)\n");
57 }
58
59
60 int 
61 get_args (int argc, char **argv,struct session *sess)
62 {
63     struct filter *filt;
64     struct host_tag *tg;
65     int opt;
66     
67
68     sess->opt_debug = 0;
69     DEB_DISC=0;
70     DEB_DISC2=0;
71     sess->log_to_fd = 1;
72     sess->np = 0;
73     sess->opt_daemonize = 0;
74     
75     sess->log_to_fd = fileno (stdout);
76     
77 /* defaults to eth0 */
78     strcpy (sess->name, "eth0");
79     
80     
81     if ((sess->filt=malloc(sizeof(struct filter))) == NULL) {
82         poe_error (sess,"failed to malloc for Filter ");
83         poe_die (-1);
84     }
85     
86     filt=sess->filt;  /* makes the code more readable */
87     memset(filt,0,sizeof(struct filter));
88     
89     filt->num_restart=1;
90     
91 /* set default filters; move this to routine */
92     /* parse options */
93     
94     while ((opt = getopt (argc, argv, "A:C:E:d:DR:I:F:L:V:P:SN:GH")) != -1)
95         
96         switch (opt) {
97         case 'R':                       /* sets number of retries */
98             filt->num_restart = strtol (optarg, (char **) NULL, 10);
99             filt->num_restart += 1;
100             break;
101         case 'I':                       /* sets interface */
102             if (strlen (optarg) >= IFNAMSIZ) {
103                 poe_error (sess,"interface name cannot exceed %d characters", IFNAMSIZ - 1);
104                 return (-1);
105             }
106             strncpy (sess->name, optarg, strlen(optarg)+1);
107             break;
108         case 'C':                       /* name of the file in /etc/ppp/peers */
109             if (NULL != filt->fname) {
110                 poe_error (sess,"-F can not be used with -C");
111                 return (-1);
112             }
113             if (strlen(optarg) > MAX_FNAME) {
114                 poe_error (sess,"file name cannot exceed %d characters", MAX_FNAME - 1);
115                 return (-1);
116             }
117             filt->fname=malloc(strlen(optarg));
118             strncpy (filt->fname, optarg, strlen(optarg));
119             filt->peermode=1;
120             break;
121         case 'F':                       /* sets the options file */
122             if (NULL != filt->fname) {
123                 poe_error (sess,"-F can not be used with -C");
124                 return (-1);
125             }
126             
127             if (strlen(optarg) > MAX_FNAME) {
128                 poe_error (sess,"file name cannot exceed %d characters", MAX_FNAME - 1);
129                 return (-1);
130             }
131             filt->fname=malloc(strlen(optarg)+1);
132             strncpy (filt->fname, optarg, strlen(optarg)+1);
133             
134             poe_info (sess,"selected %s as filename\n",filt->fname);
135             break;
136         case 'D':                       /* don't daemonize */
137             sess->opt_daemonize = 1;
138             detached=0;
139             break;
140         case 'd':                       /* debug level */
141             sess->opt_debug = strtol (optarg, (char **) NULL, 10);
142             if (sess->opt_debug & 0x0002)
143                 DEB_DISC=1;
144             if (sess->opt_debug & 0x0004)
145                 DEB_DISC2=1;
146             break;
147         case 'P':                       /* sets the pppd binary */
148             if (strlen(optarg) > MAX_FNAME) {
149                 poe_error (sess,"pppd binary cant exceed %d characters", MAX_FNAME - 1);
150                 return (-1);
151             }
152             filt->pppd=malloc(strlen(optarg));
153             strncpy (filt->pppd, optarg, strlen(optarg));
154             break;
155         case 'H':                       
156             sess->np = 2;
157             break;
158         case 'G':                       
159             sess->np = 1;
160             break;
161         case 'V':                       /* version */
162             fprintf (stdout,"pppoe version %d.%d build %d", VERSION_MAJOR,
163                      VERSION_MINOR, VERSION_DATE);
164             return (0);
165         case 'S':                       /* server mode */
166             sess->type = SESSION_SERVER;
167             break;
168         case 'A':                       /* AC override */
169             poe_info (sess,"AC name override to %s", optarg);
170             if (strlen (optarg) > 255) {
171                 poe_error (sess," AC name too long 
172                           (maximum allowed 256 chars)");
173                 poe_die(-1);
174             }
175             if ((sess->filt->ntag= malloc (sizeof (struct pppoe_tag) + 
176                                            strlen (optarg)))== NULL) {
177                 poe_error (sess,"failed to malloc for AC name");
178                 poe_die(-1);
179             }
180             sess->filt->ntag->tag_len=htons(strlen(optarg));
181             sess->filt->ntag->tag_type=PTT_AC_NAME;
182             poe_error (sess," pppoe_ac_name: AC name Override %p\n",
183                        sess->filt->ntag);
184             strcpy(sess->filt->ntag->tag_data,optarg);
185             break;
186         case 'E':                       /* AC service name override */
187             poe_info (sess,"AC service name override to %s", optarg);
188             if (strlen (optarg) > 255) {
189                 poe_error (sess," Service name too long 
190                   (maximum allowed 256 chars)");
191                 poe_die(-1);
192             }
193             
194             if ((filt->stag = malloc (strlen (optarg) + sizeof (struct pppoe_tag))) == NULL) {
195                 poe_error (sess,"failed to malloc for service name: %m");
196                 return (-1);
197             }
198             
199             filt->stag->tag_len = htons (strlen (optarg));
200             filt->stag->tag_type = PTT_SRV_NAME;
201             strcpy ((char *) (filt->stag->tag_data), optarg);
202             break;
203         default:
204             poe_error (sess,"Unknown option '%c'", optopt);
205             print_help ();
206             return (-1);
207         }
208     
209     
210     return (1);
211     
212 }
213
214
215 int main(int argc, char** argv){
216     int ret;
217     struct filter *filt;
218     struct session *ses = (struct session *)malloc(sizeof(struct session));
219     char buf[256];
220     ses=(void *)malloc(sizeof(struct session));
221     
222     if(!ses){
223         return -1;
224     }
225     memset(ses,0,sizeof(struct session));
226     
227     
228     
229     openlog ("pppoed", LOG_PID | LOG_NDELAY, LOG_PPPOE);
230     setlogmask (LOG_UPTO (ses->opt_debug ? LOG_DEBUG : LOG_INFO));
231     
232     
233     if ((get_args (argc,(char **) argv,ses)) <1)
234         poe_die(-1);
235     
236     filt=ses->filt;  /* makes the code more readable */
237     
238     if (!ses->np) {
239         poe_create_pidfile (ses);
240 //      signal (SIGINT, &sigproc);
241 //      signal (SIGTERM, &sigproc);
242         signal (SIGCHLD, &sigchild);
243     }
244     
245     if(ses->type == SESSION_CLIENT){
246
247         poe_info(ses,"calling client_init_ses\n");
248         ret = client_init_ses(ses,ses->name);
249     
250         if( ret < 0 ){
251             return -1;
252         }
253
254         while (ses->filt->num_restart > 0)
255         {
256             poe_info(ses,"Restart number %d ",ses->filt->num_restart);
257             ppp_connect (ses);
258             ses->filt->num_restart--;
259         }
260
261     }else if( ses->type == SESSION_SERVER ){
262
263         poe_info(ses,"calling srv_init_ses\n");
264         ret = srv_init_ses(ses,ses->name);
265
266         if( ret < 0 ){
267             return -1;
268         }
269
270         ret = 1;
271         while(ret>=0)
272             ret = ppp_connect(ses);
273     
274     }
275
276     
277     
278     
279     poe_info(ses,"ppp_connect came back! %d",ret);
280     
281     exit(0);
282     
283 }