1/* PPPoE support library "libpppoe" 2 * 3 * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>, 4 * Jamal Hadi Salim <hadi@cyberus.ca> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11#include "pppoe.h" 12 13/* 14 * 15 */ 16int build_ppp_opts(char *args[],struct session *ses) 17{ 18 char buf[256]; 19 int retval=0,i=0; 20 21 memset(buf,0,256); 22 23/* pppds path */ 24 if ( NULL != ses->filt->pppd){ 25 args[0]=(char *)malloc(strlen(ses->filt->pppd)); 26 strcpy (args[0],ses->filt->pppd); 27 } else { 28 args[0]=(char *)malloc(strlen(_PATH_PPPD)); 29 strcpy (args[0],_PATH_PPPD); 30 } 31 32/* long device name */ 33 snprintf(buf, 256,"%02x:%02x:%02x:%02x:%02x:%02x/%04x/%s", 34 ses->remote.sll_addr[0], 35 ses->remote.sll_addr[1], 36 ses->remote.sll_addr[2], 37 ses->remote.sll_addr[3], 38 ses->remote.sll_addr[4], 39 ses->remote.sll_addr[5], 40 ses->sp.sa_addr.pppoe.sid, 41 ses->name); 42 args[1]=(char *)malloc(strlen(buf)); 43 strcpy(args[1],buf); 44 45 i=2; 46 47/* override options file */ 48 if (NULL != ses->filt->fname ) { 49 50 if (!ses->filt->peermode) { 51 args[i]=(char *)malloc(strlen("file")); 52 strcpy (args[i],"file"); 53 i++; 54 args[i]=(char *)malloc(strlen(ses->filt->fname)+1); 55 strcpy (args[i],ses->filt->fname); 56 i++; 57 } else{ /* peermode */ 58 args[i]=(char *)malloc(strlen("call")); 59 strcpy (args[i],"call"); 60 i++; 61 args[i]=(char *)malloc(strlen(ses->filt->fname)+1); 62 strcpy (args[i],ses->filt->fname); 63 i++; 64 } 65 } 66 67/* user requested for a specific name */ 68 if (NULL != ses->filt->ntag) { 69 if ( NULL != ses->filt->ntag->tag_data) { 70 args[i]=(char *)malloc(strlen("pppoe_ac_name")); 71 strcpy(args[i],"pppoe_ac_name"); 72 i++; 73 args[i]=(char *)malloc(ntohs(ses->filt->ntag->tag_len)); 74 strcpy(args[i],ses->filt->ntag->tag_data); 75 i++; 76 } 77 } 78/* user requested for a specific service name */ 79 if (NULL != ses->filt->stag) { 80 if ( NULL != ses->filt->stag->tag_data) { 81 args[i]=(char *)malloc(strlen("pppoe_srv_name")); 82 strcpy(args[i],"pppoe_srv_name"); 83 i++; 84 args[i]=(char *)malloc(ntohs(ses->filt->stag->tag_len)); 85 strcpy(args[i],ses->filt->stag->tag_data); 86 i++; 87 } 88 } 89 90/* 91 */ 92 if (ses->opt_daemonize) { 93 args[i]=(char *)malloc(strlen("nodetach")); 94 strcpy(args[i],"nodetach"); 95 i++; 96 } 97 98 args[i]=NULL; 99 { 100 int j; 101 poe_info(ses,"calling pppd with %d args\n",i); 102 j=i; 103 for (i=0; i<j,NULL !=args[i]; i++) { 104 poe_info(ses," <%d: %s > \n",i,args[i]); 105 } 106 } 107 return retval; 108} 109 110 111/* 112 * 113 */ 114int ppp_connect (struct session *ses) 115{ 116 int ret,pid; 117 char *args[32]; 118 119 120 poe_info(ses,"calling ses_connect\n"); 121 do{ 122 ret = session_connect(ses); 123 }while(ret == 0); 124 125 if (ret > 0 ) 126 if (ses->np == 1 && ret == 1) 127 return ses->np; /* -G */ 128 if (ses->np == 2) 129 return ses->np; /* -H */ 130 131 if( ret <= 0){ 132 return ret; 133 } 134 135 poe_info(ses,"DONE calling ses_connect np is %d \n",ses->np); 136 137 138 pid = fork (); 139 if (pid < 0) { 140 poe_error (ses,"unable to fork() for pppd: %m"); 141 poe_die (-1); 142 } 143 144 145 if(!pid) { 146 poe_info(ses,"calling build_ppp_opts\n"); 147 if (0> build_ppp_opts(args,ses)) { 148 poe_error(ses,"ppp_connect: failed to build ppp_opts\n"); 149 return -1; 150 } 151 execvp(args[0],args); 152 poe_info (ses," child got killed"); 153 } else if( ses->type == SESSION_CLIENT) { 154 if (!ses->opt_daemonize) 155 return 1; 156 pause(); 157 poe_info (ses," OK we got killed"); 158 return -1; 159 } 160 return 1; 161} 162 163