diff -u -r -N a/ppp/pppd/options.c ppp/pppd/options.c --- a/ppp/pppd/options.c 2003-03-03 06:11:46.000000000 +0100 +++ b/pppd/options.c 2003-07-01 11:17:12.000000000 +0200 @@ -843,6 +843,22 @@ } /* + * remove_option - permanently remove an option from consideration... + * for use by modules to remove choices which no longer make sense. + * returns true if found an option + */ +int remove_option(const char *name) +{ + option_t *o; + + o = find_option(name); + if (o == NULL) + return 0; + o->name = ""; + return 1; +} + +/* * check_options - check that options are valid and consistent. */ void diff -u -r -N a/ppp/pppd/plugins/Makefile.linux ppp/pppd/plugins/Makefile.linux --- a/ppp/pppd/plugins/Makefile.linux 2003-02-16 23:31:24.000000000 +0100 +++ b/pppd/plugins/Makefile.linux 2003-07-01 11:39:05.000000000 +0200 @@ -6,7 +6,7 @@ SUBDIRS := rp-pppoe # Uncomment the next line to include the radius authentication plugin # SUBDIRS += radius -PLUGINS := minconn.so passprompt.so passwordfd.so +PLUGINS := minconn.so passprompt.so passwordfd.so pppoatm.so # include dependencies if present ifeq (.depend,$(wildcard .depend)) @@ -16,6 +16,9 @@ all: $(PLUGINS) for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all; done +pppoatm.so: pppoatm.c + $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ -latm + %.so: %.c $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ diff -u -r -N a/ppp/pppd/plugins/pppoatm.c ppp/pppd/plugins/pppoatm.c --- /dev/null 1970-01-01 01:00:00.000000000 +0100 +++ b/pppd/plugins/pppoatm.c 2003-07-01 11:39:37.000000000 +0200 @@ -0,0 +1,232 @@ +/* pppoatm.c - pppd plugin to implement PPPoATM protocol. + * + * Copyright 2000 Mitchell Blank Jr. + * Based in part on work from Jens Axboe and Paul Mackerras. + * Updated to ppp-2.4.1 by Bernhard Kaindl + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include "pppd.h" +#include "pathnames.h" +#include "fsm.h" /* Needed for lcp.h to include cleanly */ +#include "lcp.h" +#include +#include +#include +#include +#include +#include + +const char pppd_version[] = VERSION; + +static struct sockaddr_atmpvc pvcaddr; +static char *qosstr = NULL; +//static int pppoatm_accept = 0; +static bool llc_encaps = 0; +static bool vc_encaps = 0; +static int device_got_set = 0; +static int pppoatm_max_mtu, pppoatm_max_mru; +static int setdevname_pppoatm(const char *cp, const char **argv, int doit); +struct channel pppoa_channel; + +static option_t pppoa_options[] = { + { "device name", o_wild, (void *) &setdevname_pppoatm, + "ATM service provider IDs: VPI.VCI", + OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, + devnam}, +#if 0 + { "accept", o_bool, &pppoatm_accept, + "set PPPoATM socket to accept incoming connections", 1 }, +#endif + { "llc-encaps", o_bool, &llc_encaps, + "use LLC encapsulation for PPPoATM", 1}, + { "vc-encaps", o_bool, &vc_encaps, + "use VC multiplexing for PPPoATM (default)", 1}, + { "qos", o_string, &qosstr, + "set QoS for PPPoATM connection", 1}, + { NULL } +}; + +/* returns: + * -1 if there's a problem with setting the device + * 0 if we can't parse "cp" as a valid name of a device + * 1 if "cp" is a reasonable thing to name a device + * Note that we don't actually open the device at this point + * We do need to fill in: + * devnam: a string representation of the device + * devstat: a stat structure of the device. In this case + * we're not opening a device, so we just make sure + * to set up S_ISCHR(devstat.st_mode) != 1, so we + * don't get confused that we're on stdin. + */ +int (*old_setdevname_hook)(const char* cp) = NULL; +static int setdevname_pppoatm(const char *cp, const char **argv, int doit) +{ + struct sockaddr_atmpvc addr; + extern struct stat devstat; + if (device_got_set) + return 0; + //info("PPPoATM setdevname_pppoatm: '%s'", cp); + memset(&addr, 0, sizeof addr); + if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr), + T2A_PVC | T2A_NAME) < 0) { + if(doit) + info("atm does not recognize: %s", cp); + return 0; + } + if (!doit) return 1; + //if (!dev_set_ok()) return -1; + memcpy(&pvcaddr, &addr, sizeof pvcaddr); + strlcpy(devnam, cp, sizeof devnam); + devstat.st_mode = S_IFSOCK; + if (the_channel != &pppoa_channel) { + static char *bad_options[] = { + "noaccomp", "-ac", + "default-asyncmap", "-am", "asyncmap", "-as", "escape", + "receive-all", + "crtscts", "-crtscts", "nocrtscts", + "cdtrcts", "nocdtrcts", + "xonxoff", + "modem", "local", "sync", + NULL }; + char **a; + the_channel = &pppoa_channel; + info("PPPoATM setdevname - remove unwanted options"); + for (a = bad_options; *a != NULL; a++) + remove_option(*a); + modem = 0; + lcp_wantoptions[0].neg_accompression = 0; + lcp_allowoptions[0].neg_accompression = 0; + lcp_wantoptions[0].neg_asyncmap = 0; + lcp_allowoptions[0].neg_asyncmap = 0; + lcp_wantoptions[0].neg_pcompression = 0; + } + info("PPPoATM setdevname_pppoatm - SUCCESS:%s", cp); + device_got_set = 1; + return 1; +} + +#define pppoatm_overhead() (llc_encaps ? 6 : 2) + +static void no_device_given_pppoatm(void) +{ + fatal("No vpi.vci specified"); +} + +static void set_line_discipline_pppoatm(int fd) +{ + struct atm_backend_ppp be; + be.backend_num = ATM_BACKEND_PPP; + if (!llc_encaps) + be.encaps = PPPOATM_ENCAPS_VC; + else if (!vc_encaps) + be.encaps = PPPOATM_ENCAPS_LLC; + else + be.encaps = PPPOATM_ENCAPS_AUTODETECT; + if (ioctl(fd, ATM_SETBACKEND, &be) < 0) + fatal("ioctl(ATM_SETBACKEND): %m"); +} + +#if 0 +static void reset_line_discipline_pppoatm(int fd) +{ + atm_backend_t be = ATM_BACKEND_RAW; + /* 2.4 doesn't support this yet */ + (void) ioctl(fd, ATM_SETBACKEND, &be); +} +#endif + +static int connect_pppoatm(void) +{ + int fd; + struct atm_qos qos; + + system ("/sbin/modprobe pppoatm"); + + if (!device_got_set) + no_device_given_pppoatm(); + fd = socket(AF_ATMPVC, SOCK_DGRAM, 0); + if (fd < 0) + fatal("failed to create socket: %m"); + memset(&qos, 0, sizeof qos); + qos.txtp.traffic_class = qos.rxtp.traffic_class = ATM_UBR; + /* TODO: support simplified QoS setting */ + if (qosstr != NULL) + if (text2qos(qosstr, &qos, 0)) + fatal("Can't parse QoS: \"%s\""); + qos.txtp.max_sdu = lcp_allowoptions[0].mru + pppoatm_overhead(); + qos.rxtp.max_sdu = lcp_wantoptions[0].mru + pppoatm_overhead(); + qos.aal = ATM_AAL5; + if (setsockopt(fd, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) + fatal("setsockopt(SO_ATMQOS): %m"); + /* TODO: accept on SVCs... */ + if (connect(fd, (struct sockaddr *) &pvcaddr, + sizeof(struct sockaddr_atmpvc))) + fatal("connect(%s): %m", devnam); + pppoatm_max_mtu = lcp_allowoptions[0].mru; + pppoatm_max_mru = lcp_wantoptions[0].mru; + set_line_discipline_pppoatm(fd); + strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); + return fd; +} + +static void send_config_pppoa(int mtu, + u_int32_t asyncmap, + int pcomp, + int accomp) +{ + int sock; + struct ifreq ifr; + if (mtu > pppoatm_max_mtu) + error("Couldn't increase MTU to %d", mtu); + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) + fatal("Couldn't create IP socket: %m"); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + ifr.ifr_mtu = mtu; + if (ioctl(sock, SIOCSIFMTU, (caddr_t) &ifr) < 0) + fatal("ioctl(SIOCSIFMTU): %m"); + (void) close (sock); +} + +static void recv_config_pppoa(int mru, + u_int32_t asyncmap, + int pcomp, + int accomp) +{ + if (mru > pppoatm_max_mru) + error("Couldn't increase MRU to %d", mru); +} + +void plugin_init(void) +{ +#if defined(__linux__) + extern int new_style_driver; /* From sys-linux.c */ + if (!ppp_available() && !new_style_driver) + fatal("Kernel doesn't support ppp_generic - " + "needed for PPPoATM"); +#else + fatal("No PPPoATM support on this OS"); +#endif + info("PPPoATM plugin_init"); + add_options(pppoa_options); +} +struct channel pppoa_channel = { + options: pppoa_options, + process_extra_options: NULL, + check_options: NULL, + connect: &connect_pppoatm, + disconnect: NULL, + establish_ppp: &generic_establish_ppp, + disestablish_ppp: &generic_disestablish_ppp, + send_config: &send_config_pppoa, + recv_config: &recv_config_pppoa, + close: NULL, + cleanup: NULL +}; diff -u -r -N a/ppp/pppd/pppd.h ppp/pppd/pppd.h --- a/ppp/pppd/pppd.h 2003-04-07 02:01:46.000000000 +0200 +++ b/pppd/pppd.h 2003-07-01 11:18:54.000000000 +0200 @@ -408,6 +408,7 @@ option_t *options; /* List of command-line options */ /* Check requested options, assign defaults */ void (*check_options) __P((void)); + int (*remove_option) __P((const char *)); /* Disable the specified option */ /* Configure interface for demand-dial */ int (*demand_conf) __P((int unit)); /* Say whether to bring up link for this pkt */