source: src/router/services/services/pppoeserver.c @ 17745

Last change on this file since 17745 was 17745, checked in by sash, 20 months ago

pppoesrv: some fixes

File size: 12.0 KB
Line 
1/*
2 * pppoeserver.c
3 *
4 * Copyright (C) 2007 Sebastian Gottschall <gottschall@dd-wrt.com>
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 2
9 * of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * $Id:
21 */
22#ifdef HAVE_PPPOESERVER
23#include <stdio.h>
24#include <signal.h>
25#include <bcmnvram.h>
26#include <shutils.h>
27#include <utils.h>
28#include <malloc.h>
29#include <sys/stat.h>
30#include <syslog.h>
31#include <services.h>
32
33static char *getifip(void)
34{
35        if (nvram_match("pppoeserver_interface", "br0"))
36                return nvram_safe_get("lan_ipaddr");
37        else
38                return nvram_nget("%s_ipaddr",
39                                  nvram_safe_get("pppoeserver_interface"));
40}
41
42void add_pppoe_natrule(void)
43{
44
45        if (nvram_match("wan_proto", "disabled")) {
46                char mask[128];
47
48                sprintf(mask, "%s/%s", nvram_safe_get("pppoeserver_remotenet"),
49                        nvram_safe_get("pppoeserver_remotemask"));
50                eval("iptables", "-A", "INPUT", "-i", getifip(),
51                     "-s", mask, "-j", "DROP");
52                eval("iptables", "-t", "nat", "-A", "POSTROUTING", "-s", mask,
53                     "-j", "SNAT", "--to-source", getifip());
54        }
55}
56
57void del_pppoe_natrule(void)
58{
59        if (nvram_match("wan_proto", "disabled")) {
60                char mask[128];
61
62                sprintf(mask, "%s/%s", nvram_safe_get("pppoeserver_remotenet"),
63                        nvram_safe_get("pppoeserver_remotemask"));
64                eval("iptables", "-D", "INPUT", "-i", getifip(),
65                     "-s", mask, "-j", "DROP");
66                eval("iptables", "-t", "nat", "-D", "POSTROUTING", "-s", mask,
67                     "-j", "SNAT", "--to-source", getifip());
68        }
69}
70
71static void makeipup(void)
72{
73        int mss;
74
75        if (nvram_match("mtu_enable", "1"))
76                mss = atoi(nvram_safe_get("wan_mtu")) - 40 - 108;
77        else
78                mss = 1500 - 40 - 108;
79
80        FILE *fp = fopen("/tmp/pppoeserver/ip-up", "w");
81
82        fprintf(fp, "#!/bin/sh\n" "startservice set_routes\n"   // reinitialize
83                "echo \"$PPPD_PID\t$1\t$5\t$PEERNAME\" >> /tmp/pppoe_connected\n"       //
84                //      just an uptime test
85                "echo \"$PEERNAME\t`date +%%s`\" >> /tmp/pppoe_uptime\n"        //
86                //->use something like $(( ($(date +%s) - $(date -d "$dates" +%s)) / (60*60*24*31) )) for computing uptime in the gui
87                "iptables -I FORWARD -i $1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n"      //
88                "iptables -I INPUT -i $1 -j ACCEPT\n"   //
89                "iptables -I FORWARD -i $1 -j ACCEPT\n" //
90                //      per peer shaping
91                "IN=`grep -i RP-Upstream-Speed-Limit /var/run/radattr.$1 | awk '{print $2}'`\n" //
92                "OUT=`grep -i RP-Downstream-Speed-Limit /var/run/radattr.$1 | awk '{print $2}'`\n"      //
93                "if [ ! -z $IN ] && [ ! -z $OUT ] && [ $IN -gt 0 ] && [ $OUT -gt 0 ]\n" //only if Speed limit !=0 and !empty
94                "then   tc qdisc del root dev $1\n"     //
95                "       tc qdisc del dev $1 ingress\n"  //
96                "       tc qdisc add dev $1 root tbf rate \"$OUT\"kbit latency 50ms burst \"$OUT\"kbit\n"       //
97                "       tc qdisc add dev $1 handle ffff: ingress\n"     //
98                "       tc filter add dev $1 parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate \"$IN\"kbit burst \"$IN\"kbit drop flowid :1\n"
99//tc qdisc add dev $1 root red min 150KB max 450KB limit 600KB burst 200 avpkt 1000 probability 0.02 bandwidth 100Mbit
100//eg: tc qdisc add dev $1 root red min 150KB max 450KB limit 600KB burst 200 avpkt 1000 probability 0.02 bandwidth 10Mbit
101//burst = (min+min+max)/(3*avpkt); limit = minimum: max+burst or x*max, max = 2*min
102
103                "fi\n");
104        fclose(fp);
105        fp = fopen("/tmp/pppoeserver/ip-down", "w");
106        fprintf(fp, "#!/bin/sh\n"
107                "grep -v $PPPD_PID /tmp/pppoe_connected > /tmp/pppoe_connected.tmp\n"   //
108                "mv /tmp/pppoe_connected.tmp /tmp/pppoe_connected\n"    //
109                //      just an uptime test
110                "grep -v $PEERNAME /tmp/pppoe_uptime > /tmp/pppoe_uptime.tmp\n" //
111                "mv /tmp/pppoe_uptime.tmp /tmp/pppoe_uptime\n"  //
112                //      calc connected time and volume per peer
113                "CONTIME=`grep $PEERNAME /tmp/pppoe_peer.db | awk '{print $2}'`\n"
114                "SENT=`grep $PEERNAME /tmp/pppoe_peer.db | awk '{print $3}'`\n"
115                "RCVD=`grep $PEERNAME /tmp/pppoe_peer.db | awk '{print $4}'`\n"
116                "CONTIME=$(($CONTIME+$CONNECT_TIME))\n"
117                "SENT=$(($SENT+$BYTES_SENT))\n"
118                "RCVD=$(($RCVD+$BYTES_RCVD))\n"
119                "grep -v $PEERNAME /tmp/pppoe_peer.db > /tmp/pppoe_peer.db.tmp\n"
120                "mv /tmp/pppoe_peer.db.tmp /tmp/pppoe_peer.db\n"
121                "echo \"$PEERNAME\t$CONTIME\t$SENT\t$RCVD\" >> /tmp/pppoe_peer.db\n"
122                //
123                "iptables -D FORWARD -i $1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n"      //
124                "iptables -D INPUT -i $1 -j ACCEPT\n"   //
125                "iptables -D FORWARD -i $1 -j ACCEPT\n" //
126                "tc qdisc del root dev $1\n"    //
127                "tc qdisc del dev $1 ingress\n");
128        fclose(fp);
129
130        chmod("/tmp/pppoeserver/ip-up", 0744);
131        chmod("/tmp/pppoeserver/ip-down", 0744);
132
133        //      copy existing peer data to /tmp
134        if (nvram_default_match("sys_enable_jffs2", "1", "0"))
135                system("/bin/cp /jffs/etc/freeradius/pppoe_peer.db /tmp/");
136}
137
138static void do_pppoeconfig(FILE * fp)
139{
140        int nowins = 0;
141
142        if (nvram_match("wan_wins", "0.0.0.0")) {
143                nvram_set("wan_wins", "");
144                nowins = 1;
145        }
146        if (strlen(nvram_safe_get("wan_wins")) == 0)
147                nowins = 1;
148        // fprintf (fp, "crtscts\n");
149        if (nvram_default_match("pppoeserver_bsdcomp", "0", "0"))
150                fprintf(fp, "nobsdcomp\n");
151        else
152                fprintf(fp, "bsdcomp 12\n");
153        if (nvram_default_match("pppoeserver_deflate", "0", "0"))
154                fprintf(fp, "nodeflate\n");
155        else
156                fprintf(fp, "deflate 12\n");
157        if (nvram_default_match("pppoeserver_lzs", "0", "0"))
158                fprintf(fp, "nolzs\n");
159        else
160                fprintf(fp, "lzs\n");
161        if (nvram_default_match("pppoeserver_mppc", "0", "0"))
162                fprintf(fp, "nomppc\n");
163        else
164                fprintf(fp, "mppc\n");
165        if (nvram_default_match("pppoeserver_encryption", "1", "0")) {
166                fprintf(fp, "mppe required,no56,no40,stateless\n");
167        } else
168                fprintf(fp, "nomppe\n");
169        fprintf(fp, "auth\n"
170                "refuse-eap\n"  // be sure using best auth methode
171                "refuse-pap\n"  //
172                "refuse-chap\n" //
173                "refuse-mschap\n"       //
174                "require-mschap-v2\n"
175                "nopcomp\n"     // no protocol field compression
176                "default-mru\n"
177                "default-asyncmap\n"
178                "noipdefault\n"
179                "defaultroute\n"
180                "proxyarp\n"    //
181                "noktune\n"     //
182                "netmask 255.255.255.255\n"     //
183                "ip-up-script /tmp/pppoeserver/ip-up\n" //
184                "ip-down-script /tmp/pppoeserver/ip-down\n"
185                "lcp-echo-interval %s\n"
186                "lcp-echo-failure %s\n"
187                "idle %s\n",
188                nvram_safe_get("pppoeserver_lcpechoint"),
189                nvram_safe_get("pppoeserver_lcpechofail"),
190                nvram_safe_get("pppoeserver_idle"));
191        if (!nowins) {
192                fprintf(fp, "ms-wins %s\n", nvram_safe_get("wan_wins"));
193        }
194        struct dns_lists *dns_list = get_dns_list();
195
196        if (nvram_match("dnsmasq_enable", "1")) {
197                if (strcmp(getifip(), ""))
198                        fprintf(fp, "ms-dns %s\n", getifip());
199        } else if (nvram_match("local_dns", "1")) {
200                if (dns_list && (strcmp(getifip(), "")
201                                 || strlen(dns_list->dns_server[0]) > 0
202                                 || strlen(dns_list->dns_server[1]) > 0
203                                 || strlen(dns_list->dns_server[2]) > 0)) {
204
205                        if (strcmp(getifip(), ""))
206                                fprintf(fp, "ms-dns %s\n", getifip());
207                        if (strlen(dns_list->dns_server[0]) > 0)
208                                fprintf(fp, "ms-dns %s\n",
209                                        dns_list->dns_server[0]);
210                        if (strlen(dns_list->dns_server[1]) > 0)
211                                fprintf(fp, "ms-dns %s\n",
212                                        dns_list->dns_server[1]);
213                        if (strlen(dns_list->dns_server[2]) > 0)
214                                fprintf(fp, "ms-dns %s\n",
215                                        dns_list->dns_server[2]);
216                }
217        } else {
218                if (dns_list
219                    && (strlen(dns_list->dns_server[0]) > 0
220                        || strlen(dns_list->dns_server[1]) > 0
221                        || strlen(dns_list->dns_server[2]) > 0)) {
222                        if (strlen(dns_list->dns_server[0]) > 0)
223                                fprintf(fp, "ms-dns  %s\n",
224                                        dns_list->dns_server[0]);
225                        if (strlen(dns_list->dns_server[1]) > 0)
226                                fprintf(fp, "ms-dns  %s\n",
227                                        dns_list->dns_server[1]);
228                        if (strlen(dns_list->dns_server[2]) > 0)
229                                fprintf(fp, "ms-dns  %s\n",
230                                        dns_list->dns_server[2]);
231
232                }
233        }
234
235        if (dns_list)
236                free(dns_list);
237
238}
239
240void start_pppoeserver(void)
241{
242        FILE *fp;
243        if (nvram_default_match("pppoeserver_enabled", "1", "0")) {
244                add_pppoe_natrule();
245                if (nvram_default_match("pppoeradius_enabled", "0", "0")) {
246
247                        mkdir("/tmp/pppoeserver", 0777);
248                        fp = fopen("/tmp/pppoeserver/pppoe-server-options", "wb");
249                        do_pppoeconfig(fp);
250                        fprintf(fp, "chap-secrets /tmp/pppoeserver/chap-secrets\n");
251                        fclose(fp);
252
253                        // parse chaps from nvram to file
254                        static char word[256];
255                        char *next, *wordlist;
256                        char *user, *pass, *ip, *enable;
257
258                        wordlist = nvram_safe_get("pppoeserver_chaps");
259
260                        fp = fopen("/tmp/pppoeserver/chap-secrets", "wb");
261
262                        foreach(word, wordlist, next) {
263                                pass = word;
264                                user = strsep(&pass, ":");
265                                if (!user || !pass)
266                                        continue;
267
268                                ip = pass;
269                                pass = strsep(&ip, ":");
270                                if (!pass || !ip)
271                                        continue;
272
273                                enable = ip;
274                                ip = strsep(&enable, ":");
275                                if (!ip || !enable)
276                                        continue;
277
278                                if (!strcmp(ip, "0.0.0.0"))
279                                        ip = "*";
280                                if (!strcmp(enable, "on"))
281                                        fprintf(fp, "%s * %s %s\n", user, pass,
282                                                ip);
283
284                        }
285                        fclose(fp);
286                        makeipup();
287                        // end parsing
288                } else {
289
290                        mkdir("/tmp/pppoeserver", 0777);
291                        fp =
292                            fopen("/tmp/pppoeserver/pppoe-server-options", "wb");
293                        do_pppoeconfig(fp);
294                        fprintf(fp, "login\n"   // 
295                                "plugin radius.so\n"    //
296                                "plugin radattr.so\n"   //
297                                "radius-config-file /tmp/pppoeserver/radius/radiusclient.conf\n");
298                        fclose(fp);
299                        mkdir("/tmp/pppoeserver/radius", 0777);
300                        fp = fopen("/tmp/pppoeserver/radius/radiusclient.conf",
301                                   "wb");
302                        fprintf(fp, "auth_order\tradius\n"      //
303                                "login_tries\t4\n"      //
304                                "login_timeout\t60\n"   //
305                                "nologin\t/etc/nologin\n"       //
306                                "issue\t/etc/issue\n"   //
307                                "servers\t/tmp/pppoeserver/radius/servers\n"    //
308                                "dictionary\t/etc/dictionary\n" //
309                                "login_radius\t/usr/local/sbin/login.radius\n"  //
310                                "seqfile\t/var/run/radius.seq\n"        //
311                                "mapfile\t/etc/port-id-map\n" "default_realm\n" //
312                                "radius_timeout\t10\n"  //
313                                "radius_retries\t3\n"   //
314                                "login_local\t/bin/login\n");   //
315                                if (nvram_match("pppoeserver_authserverip_backup", "0.0.0.0")) {
316                                        fprintf(fp, "authserver %s:%s\n"        //
317                                                "acctserver %s:%s\n",   //
318                                                nvram_safe_get("pppoeserver_authserverip"),
319                                                nvram_safe_get("pppoeserver_authserverport"),
320                                                nvram_safe_get("pppoeserver_authserverip"),
321                                                nvram_safe_get("pppoeserver_acctserverport"));
322                                }
323                                else {  fprintf(fp, "authserver %s:%s, %s:%s\n" //
324                                                "acctserver %s:%s, %s:%s\n",    //
325                                                nvram_safe_get("pppoeserver_authserverip"),
326                                                nvram_safe_get("pppoeserver_authserverport"),
327                                                nvram_safe_get("pppoeserver_authserverip_backup"),
328                                                nvram_safe_get("pppoeserver_authserverport_backup"),
329                                                nvram_safe_get("pppoeserver_authserverip"),
330                                                nvram_safe_get("pppoeserver_acctserverport"),
331                                                nvram_safe_get("pppoeserver_authserverip_backup"),
332                                                nvram_safe_get("pppoeserver_acctserverport_backup"));
333                                }
334                        fclose(fp);
335                        fp = fopen("/tmp/pppoeserver/radius/servers", "wb");
336                        if (nvram_match("pppoeserver_authserverip_backup", "0.0.0.0")) {                       
337                                fprintf(fp, "%s %s\n",
338                                nvram_safe_get("pppoeserver_authserverip"),
339                                nvram_safe_get("pppoeserver_sharedkey"));       // todo,
340                        }
341                        else {  fprintf(fp, "%s %s\n%s %s\n",
342                                nvram_safe_get("pppoeserver_authserverip"),
343                                nvram_safe_get("pppoeserver_sharedkey"),
344                                nvram_safe_get("pppoeserver_authserverip_backup"),
345                                nvram_safe_get("pppoeserver_sharedkey_backup"));
346                        }
347                        fclose(fp);
348                        makeipup();
349                }
350
351                //create the ip pool file
352                fp = fopen("/tmp/pppoeserver/pool", "wb");
353                fprintf(fp, "%s\n", nvram_safe_get("pppoeserver_pool"));
354                fclose(fp);
355
356                eval("pppoe-server", "-k", "-I", nvram_safe_get("pppoeserver_interface"),
357                        "-L", getifip(), "-x", nvram_safe_get("pppoeserver_sessionlimit"),
358                        "-N", "512", "-p", "/tmp/pppoeserver/pool");   
359                dd_syslog(LOG_INFO,
360                          "rp-pppoe : pppoe server successfully started\n");
361        }
362}
363
364void stop_pppoeserver(void)
365{
366        if (stop_process("pppoe-server", "pppoe server")) {
367                del_pppoe_natrule();
368                unlink("/tmp/pppoe_connected");
369        //      backup peer data
370                if (nvram_default_match("sys_enable_jffs2", "1", "0"))
371                    system("/bin/cp /tmp/pppoe_peer.db /jffs/etc/freeradius/");
372        }
373
374}
375
376#endif
Note: See TracBrowser for help on using the repository browser.