]>
Commit | Line | Data |
---|---|---|
cd1a2927 MT |
1 | diff -u -r -N a/ppp/pppd/plugins/Makefile.linux ppp/pppd/plugins/Makefile.linux |
2 | --- a/ppp/pppd/plugins/Makefile.linux 2003-02-16 23:31:24.000000000 +0100 | |
3 | +++ b/pppd/plugins/Makefile.linux 2003-07-01 11:39:05.000000000 +0200 | |
4 | @@ -6,7 +6,7 @@ | |
5 | SUBDIRS := rp-pppoe | |
6 | # Uncomment the next line to include the radius authentication plugin | |
7 | # SUBDIRS += radius | |
8 | -PLUGINS := minconn.so passprompt.so passwordfd.so | |
9 | +PLUGINS := minconn.so passprompt.so passwordfd.so pppoatm.so | |
10 | ||
11 | # include dependencies if present | |
12 | ifeq (.depend,$(wildcard .depend)) | |
13 | @@ -16,6 +16,9 @@ | |
14 | all: $(PLUGINS) | |
15 | for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all; done | |
16 | ||
17 | +pppoatm.so: pppoatm.c | |
18 | + $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ -latm -lresolv | |
19 | + | |
20 | %.so: %.c | |
21 | $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ | |
22 | ||
23 | diff -u -r -N a/ppp/pppd/plugins/pppoatm.c ppp/pppd/plugins/pppoatm.c | |
24 | --- /dev/null 1970-01-01 01:00:00.000000000 +0100 | |
25 | +++ b/pppd/plugins/pppoatm.c 2003-07-01 11:39:37.000000000 +0200 | |
26 | @@ -0,0 +1,232 @@ | |
27 | +/* pppoatm.c - pppd plugin to implement PPPoATM protocol. | |
28 | + * | |
29 | + * Copyright 2000 Mitchell Blank Jr. | |
30 | + * Based in part on work from Jens Axboe and Paul Mackerras. | |
31 | + * Updated to ppp-2.4.1 by Bernhard Kaindl | |
32 | + * | |
33 | + * This program is free software; you can redistribute it and/or | |
34 | + * modify it under the terms of the GNU General Public License | |
35 | + * as published by the Free Software Foundation; either version | |
36 | + * 2 of the License, or (at your option) any later version. | |
37 | + */ | |
38 | +#include <unistd.h> | |
39 | +#include <string.h> | |
40 | +#include <stdlib.h> | |
41 | +#include "pppd.h" | |
42 | +#include "pathnames.h" | |
43 | +#include "fsm.h" /* Needed for lcp.h to include cleanly */ | |
44 | +#include "lcp.h" | |
45 | +#include <atm.h> | |
46 | +#include <linux/atmdev.h> | |
47 | +#include <linux/atmppp.h> | |
48 | +#include <sys/stat.h> | |
49 | +#include <net/if.h> | |
50 | +#include <sys/ioctl.h> | |
51 | + | |
52 | +const char pppd_version[] = VERSION; | |
53 | + | |
54 | +static struct sockaddr_atmpvc pvcaddr; | |
55 | +static char *qosstr = NULL; | |
56 | +/* static int pppoatm_accept = 0; */ | |
57 | +static bool llc_encaps = 0; | |
58 | +static bool vc_encaps = 0; | |
59 | +static int device_got_set = 0; | |
60 | +static int pppoatm_max_mtu, pppoatm_max_mru; | |
61 | +static int setdevname_pppoatm(const char *cp, const char **argv, int doit); | |
62 | +struct channel pppoa_channel; | |
63 | + | |
64 | +static option_t pppoa_options[] = { | |
65 | + { "device name", o_wild, (void *) &setdevname_pppoatm, | |
66 | + "ATM service provider IDs: VPI.VCI", | |
67 | + OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, | |
68 | + devnam}, | |
69 | +#if 0 | |
70 | + { "accept", o_bool, &pppoatm_accept, | |
71 | + "set PPPoATM socket to accept incoming connections", 1 }, | |
72 | +#endif | |
73 | + { "llc-encaps", o_bool, &llc_encaps, | |
74 | + "use LLC encapsulation for PPPoATM", 1}, | |
75 | + { "vc-encaps", o_bool, &vc_encaps, | |
76 | + "use VC multiplexing for PPPoATM (default)", 1}, | |
77 | + { "qos", o_string, &qosstr, | |
78 | + "set QoS for PPPoATM connection", 1}, | |
79 | + { NULL } | |
80 | +}; | |
81 | + | |
82 | +/* returns: | |
83 | + * -1 if there's a problem with setting the device | |
84 | + * 0 if we can't parse "cp" as a valid name of a device | |
85 | + * 1 if "cp" is a reasonable thing to name a device | |
86 | + * Note that we don't actually open the device at this point | |
87 | + * We do need to fill in: | |
88 | + * devnam: a string representation of the device | |
89 | + * devstat: a stat structure of the device. In this case | |
90 | + * we're not opening a device, so we just make sure | |
91 | + * to set up S_ISCHR(devstat.st_mode) != 1, so we | |
92 | + * don't get confused that we're on stdin. | |
93 | + */ | |
94 | +int (*old_setdevname_hook)(const char* cp) = NULL; | |
95 | +static int setdevname_pppoatm(const char *cp, const char **argv, int doit) | |
96 | +{ | |
97 | + struct sockaddr_atmpvc addr; | |
98 | + extern struct stat devstat; | |
99 | + if (device_got_set) | |
100 | + return 0; | |
101 | + //info("PPPoATM setdevname_pppoatm: '%s'", cp); | |
102 | + memset(&addr, 0, sizeof addr); | |
103 | + if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr), | |
104 | + T2A_PVC | T2A_NAME) < 0) { | |
105 | + if(doit) | |
106 | + info("atm does not recognize: %s", cp); | |
107 | + return 0; | |
108 | + } | |
109 | + if (!doit) return 1; | |
110 | + //if (!dev_set_ok()) return -1; | |
111 | + memcpy(&pvcaddr, &addr, sizeof pvcaddr); | |
112 | + strlcpy(devnam, cp, sizeof devnam); | |
113 | + devstat.st_mode = S_IFSOCK; | |
114 | + if (the_channel != &pppoa_channel) { | |
115 | + static char *bad_options[] = { | |
116 | + "noaccomp", "-ac", | |
117 | + "default-asyncmap", "-am", "asyncmap", "-as", "escape", | |
118 | + "receive-all", | |
119 | + "crtscts", "-crtscts", "nocrtscts", | |
120 | + "cdtrcts", "nocdtrcts", | |
121 | + "xonxoff", | |
122 | + "modem", "local", "sync", | |
123 | + NULL }; | |
124 | + char **a; | |
125 | + the_channel = &pppoa_channel; | |
126 | + info("PPPoATM setdevname - remove unwanted options"); | |
127 | + for (a = bad_options; *a != NULL; a++) | |
128 | + remove_option(*a); | |
129 | + modem = 0; | |
130 | + lcp_wantoptions[0].neg_accompression = 0; | |
131 | + lcp_allowoptions[0].neg_accompression = 0; | |
132 | + lcp_wantoptions[0].neg_asyncmap = 0; | |
133 | + lcp_allowoptions[0].neg_asyncmap = 0; | |
134 | + lcp_wantoptions[0].neg_pcompression = 0; | |
135 | + } | |
136 | + info("PPPoATM setdevname_pppoatm - SUCCESS:%s", cp); | |
137 | + device_got_set = 1; | |
138 | + return 1; | |
139 | +} | |
140 | + | |
141 | +#define pppoatm_overhead() (llc_encaps ? 6 : 2) | |
142 | + | |
143 | +static void no_device_given_pppoatm(void) | |
144 | +{ | |
145 | + fatal("No vpi.vci specified"); | |
146 | +} | |
147 | + | |
148 | +static void set_line_discipline_pppoatm(int fd) | |
149 | +{ | |
150 | + struct atm_backend_ppp be; | |
151 | + be.backend_num = ATM_BACKEND_PPP; | |
152 | + if (!llc_encaps) | |
153 | + be.encaps = PPPOATM_ENCAPS_VC; | |
154 | + else if (!vc_encaps) | |
155 | + be.encaps = PPPOATM_ENCAPS_LLC; | |
156 | + else | |
157 | + be.encaps = PPPOATM_ENCAPS_AUTODETECT; | |
158 | + if (ioctl(fd, ATM_SETBACKEND, &be) < 0) | |
159 | + fatal("ioctl(ATM_SETBACKEND): %m"); | |
160 | +} | |
161 | + | |
162 | +#if 0 | |
163 | +static void reset_line_discipline_pppoatm(int fd) | |
164 | +{ | |
165 | + atm_backend_t be = ATM_BACKEND_RAW; | |
166 | + /* 2.4 doesn't support this yet */ | |
167 | + (void) ioctl(fd, ATM_SETBACKEND, &be); | |
168 | +} | |
169 | +#endif | |
170 | + | |
171 | +static int connect_pppoatm(void) | |
172 | +{ | |
173 | + int fd; | |
174 | + struct atm_qos qos; | |
175 | + | |
176 | + system ("/sbin/modprobe pppoatm"); | |
177 | + | |
178 | + if (!device_got_set) | |
179 | + no_device_given_pppoatm(); | |
180 | + fd = socket(AF_ATMPVC, SOCK_DGRAM, 0); | |
181 | + if (fd < 0) | |
182 | + fatal("failed to create socket: %m"); | |
183 | + memset(&qos, 0, sizeof qos); | |
184 | + qos.txtp.traffic_class = qos.rxtp.traffic_class = ATM_UBR; | |
185 | + /* TODO: support simplified QoS setting */ | |
186 | + if (qosstr != NULL) | |
187 | + if (text2qos(qosstr, &qos, 0)) | |
188 | + fatal("Can't parse QoS: \"%s\""); | |
189 | + qos.txtp.max_sdu = lcp_allowoptions[0].mru + pppoatm_overhead(); | |
190 | + qos.rxtp.max_sdu = lcp_wantoptions[0].mru + pppoatm_overhead(); | |
191 | + qos.aal = ATM_AAL5; | |
192 | + if (setsockopt(fd, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) | |
193 | + fatal("setsockopt(SO_ATMQOS): %m"); | |
194 | + /* TODO: accept on SVCs... */ | |
195 | + if (connect(fd, (struct sockaddr *) &pvcaddr, | |
196 | + sizeof(struct sockaddr_atmpvc))) | |
197 | + fatal("connect(%s): %m", devnam); | |
198 | + pppoatm_max_mtu = lcp_allowoptions[0].mru; | |
199 | + pppoatm_max_mru = lcp_wantoptions[0].mru; | |
200 | + set_line_discipline_pppoatm(fd); | |
201 | + strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); | |
202 | + return fd; | |
203 | +} | |
204 | + | |
205 | +static void send_config_pppoa(int mtu, | |
206 | + u_int32_t asyncmap, | |
207 | + int pcomp, | |
208 | + int accomp) | |
209 | +{ | |
210 | + int sock; | |
211 | + struct ifreq ifr; | |
212 | + if (mtu > pppoatm_max_mtu) | |
213 | + error("Couldn't increase MTU to %d", mtu); | |
214 | + sock = socket(AF_INET, SOCK_DGRAM, 0); | |
215 | + if (sock < 0) | |
216 | + fatal("Couldn't create IP socket: %m"); | |
217 | + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); | |
218 | + ifr.ifr_mtu = mtu; | |
219 | + if (ioctl(sock, SIOCSIFMTU, (caddr_t) &ifr) < 0) | |
220 | + fatal("ioctl(SIOCSIFMTU): %m"); | |
221 | + (void) close (sock); | |
222 | +} | |
223 | + | |
224 | +static void recv_config_pppoa(int mru, | |
225 | + u_int32_t asyncmap, | |
226 | + int pcomp, | |
227 | + int accomp) | |
228 | +{ | |
229 | + if (mru > pppoatm_max_mru) | |
230 | + error("Couldn't increase MRU to %d", mru); | |
231 | +} | |
232 | + | |
233 | +void plugin_init(void) | |
234 | +{ | |
235 | +#if defined(__linux__) | |
236 | + extern int new_style_driver; /* From sys-linux.c */ | |
237 | + if (!ppp_available() && !new_style_driver) | |
238 | + fatal("Kernel doesn't support ppp_generic - " | |
239 | + "needed for PPPoATM"); | |
240 | +#else | |
241 | + fatal("No PPPoATM support on this OS"); | |
242 | +#endif | |
243 | + info("PPPoATM plugin_init"); | |
244 | + add_options(pppoa_options); | |
245 | +} | |
246 | +struct channel pppoa_channel = { | |
247 | + options: pppoa_options, | |
248 | + process_extra_options: NULL, | |
249 | + check_options: NULL, | |
250 | + connect: &connect_pppoatm, | |
251 | + disconnect: NULL, | |
252 | + establish_ppp: &generic_establish_ppp, | |
253 | + disestablish_ppp: &generic_disestablish_ppp, | |
254 | + send_config: &send_config_pppoa, | |
255 | + recv_config: &recv_config_pppoa, | |
256 | + close: NULL, | |
257 | + cleanup: NULL | |
258 | +}; | |
259 | diff -u -r -N a/ppp/pppd/options.c ppp/pppd/options.c | |
260 | --- a/ppp/pppd/options.c 2003-03-03 06:11:46.000000000 +0100 | |
261 | +++ b/pppd/options.c 2003-07-01 11:17:12.000000000 +0200 | |
262 | @@ -843,6 +843,22 @@ | |
263 | } | |
264 | ||
265 | /* | |
266 | + * remove_option - permanently remove an option from consideration... | |
267 | + * for use by modules to remove choices which no longer make sense. | |
268 | + * returns true if found an option | |
269 | + */ | |
270 | +int remove_option(const char *name) | |
271 | +{ | |
272 | + option_t *o; | |
273 | + | |
274 | + o = find_option(name); | |
275 | + if (o == NULL) | |
276 | + return 0; | |
277 | + o->name = ""; | |
278 | + return 1; | |
279 | +} | |
280 | + | |
281 | +/* | |
282 | * check_options - check that options are valid and consistent. | |
283 | */ | |
284 | void |