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