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 13int detached=1; 14void 15sigproc (int src) 16{ 17 int i; 18 fprintf (stderr,"Received signal %d", src); 19} 20 21void 22sigchild (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 36void 37print_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 60int 61get_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 strcpy(sess->filt->ntag->tag_data,optarg); 183 break; 184 case 'E': /* AC service name override */ 185 poe_info (sess,"AC service name override to %s", optarg); 186 if (strlen (optarg) > 255) { 187 poe_error (sess," Service name too long 188 (maximum allowed 256 chars)"); 189 poe_die(-1); 190 } 191 192 if ((filt->stag = malloc (strlen (optarg) + sizeof (struct pppoe_tag))) == NULL) { 193 poe_error (sess,"failed to malloc for service name: %m"); 194 return (-1); 195 } 196 197 filt->stag->tag_len = htons (strlen (optarg)); 198 filt->stag->tag_type = PTT_SRV_NAME; 199 strcpy ((char *) (filt->stag->tag_data), optarg); 200 break; 201 default: 202 poe_error (sess,"Unknown option '%c'", optopt); 203 print_help (); 204 return (-1); 205 } 206 207 208 return (1); 209 210} 211 212 213int main(int argc, char** argv){ 214 int ret; 215 struct filter *filt; 216 struct session *ses = (struct session *)malloc(sizeof(struct session)); 217 char buf[256]; 218 ses=(void *)malloc(sizeof(struct session)); 219 220 if(!ses){ 221 return -1; 222 } 223 memset(ses,0,sizeof(struct session)); 224 225 226 227 openlog ("pppoed", LOG_PID | LOG_NDELAY, LOG_PPPOE); 228 setlogmask (LOG_UPTO (ses->opt_debug ? LOG_DEBUG : LOG_INFO)); 229 230 231 if ((get_args (argc,(char **) argv,ses)) <1) 232 poe_die(-1); 233 234 filt=ses->filt; /* makes the code more readable */ 235 236 if (!ses->np) { 237 poe_create_pidfile (ses); 238// signal (SIGINT, &sigproc); 239// signal (SIGTERM, &sigproc); 240 signal (SIGCHLD, &sigchild); 241 } 242 243 if(ses->type == SESSION_CLIENT){ 244 245 poe_info(ses,"calling client_init_ses\n"); 246 ret = client_init_ses(ses,ses->name); 247 248 if( ret < 0 ){ 249 return -1; 250 } 251 252 while (ses->filt->num_restart > 0) 253 { 254 poe_info(ses,"Restart number %d ",ses->filt->num_restart); 255 ppp_connect (ses); 256 ses->filt->num_restart--; 257 } 258 259 }else if( ses->type == SESSION_SERVER ){ 260 261 poe_info(ses,"calling srv_init_ses\n"); 262 ret = srv_init_ses(ses,ses->name); 263 264 if( ret < 0 ){ 265 return -1; 266 } 267 268 ret = 1; 269 while(ret>=0) 270 ret = ppp_connect(ses); 271 272 } 273 274 275 276 277 poe_info(ses,"ppp_connect came back! %d",ret); 278 279 exit(0); 280 281} 282