diff options
author | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-08-30 21:48:55 +0000 |
---|---|---|
committer | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-08-30 21:48:55 +0000 |
commit | e2383cfa769550fd700038299bc477095057a9f6 (patch) | |
tree | c4f508460d4014e780cc94d93ddf536a685c96d4 /ppp | |
parent | ae208f48dd39690ca18f5cd788af2200eb182297 (diff) |
add a proper plugin for Zaptel support in pppd, so that it can be used with any distro-supplied version of pppd instead of requiring a patched copy from the Digium download site
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@2983 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'ppp')
-rw-r--r-- | ppp/Makefile | 25 | ||||
-rw-r--r-- | ppp/zaptel.c | 339 |
2 files changed, 364 insertions, 0 deletions
diff --git a/ppp/Makefile b/ppp/Makefile new file mode 100644 index 0000000..a068fa2 --- /dev/null +++ b/ppp/Makefile @@ -0,0 +1,25 @@ +CC = gcc +COPTS = -O2 -g +CFLAGS = $(COPTS) -I.. -fPIC +LDFLAGS = -shared +INSTALL = install + +DESTDIR = /usr + +VERSION := $(shell awk -F '"' '/VERSION/ { print $$2; }' $(DESTDIR)/include/pppd/patchlevel.h) + +LIBDIR := $(DESTDIR)/lib/pppd/$(VERSION) + +PLUGINS := zaptel.so + +all: $(PLUGINS) + +%.so: %.c + $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ + +install: $(PLUGINS) + $(INSTALL) -d $(LIBDIR) + $(INSTALL) -m 0644 $? $(LIBDIR) + +clean: + rm -f *.o *.so *.a diff --git a/ppp/zaptel.c b/ppp/zaptel.c new file mode 100644 index 0000000..f203765 --- /dev/null +++ b/ppp/zaptel.c @@ -0,0 +1,339 @@ +/* zaptel.c - pppd plugin to implement PPP over Zaptel HDLC channel. + * + * Copyright 2002 Digium, Inc. + * Mark Spencer <markster@digium.inc> + * + * Borrows from PPPoE by Michal Ostrowski <mostrows@styx.uwaterloo.ca>, + * Jamal Hadi Salim <hadi@cyberus.ca> + * + * which in turn... + * + * Borrows heavily from the PPPoATM plugin by Mitchell Blank Jr., + * which is based in part on work from Jens Axboe and Paul Mackerras. + * + * 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 <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <errno.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <pppd/pppd.h> +#include <pppd/fsm.h> +#include <pppd/lcp.h> +#include <pppd/ipcp.h> +#include <pppd/ccp.h> +#include <pppd/pathnames.h> + +#include "zaptel.h" + +extern int new_style_driver; + +const char pppd_version[] = VERSION; + +#define _PATH_ZAPOPT _ROOT_PATH "/etc/ppp/options." + +#define ZAP_MTU (ZT_DEFAULT_MTU_MRU - 16) +extern int kill_link; +static char *bad_options[] = { + "noaccomp", + "-ac", + "default-asyncmap", + "-am", + "asyncmap", + "-as", + "escape", + "multilink", + "receive-all", + "crtscts", + "-crtscts", + "nocrtscts", + "cdtrcts", + "nocdtrcts", + "xonxoff", + "modem", + "local", + "sync", + "deflate", + "nodeflate", + "vj", + "novj", + "nobsdcomp", + "bsdcomp", + "-bsdcomp", + NULL +}; +#if 0 +static char *bad_options[] = { + "noaccomp", + "-ac", + "default-asyncmap", + "-am", + "asyncmap", + "-as", + "escape", + "receive-all", + "crtscts", + "-crtscts", + "nocrtscts", + "cdtrcts", + "nocdtrcts", + "xonxoff", + "modem", + "local", + "sync", + NULL +}; +#endif +int retries = 0; + +int setdevname_zaptel(const char *cp); + +static option_t zaptel_options[] = { + { "device name", o_wild, (void *) &setdevname_zaptel, + "Serial port device name", + OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, + devnam}, + { NULL } +}; + +static int zapfd = -1; +static int zapchan = 0; + +static int connect_zaptel(void) +{ + + ZT_PARAMS ztp; + int res; + int x; + + info("Zaptel device is '%s'\n", devnam); + + strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); + + if (strlen(devnam) && strcmp(devnam, "stdin")) { + /* Get the channel number */ + zapchan = atoi(devnam); + if (zapchan < 1) { + fatal("'%s' is not a valid device name\n", devnam); + return -1; + } + + /* Open /dev/zap/channel interface */ + zapfd = open("/dev/zap/channel", O_RDWR); + if (zapfd < 0) { + fatal("Unable to open zaptel channel interface: '%s'\n", strerror(errno)); + return zapfd; + } + + /* Specify which channel we really want */ + x = zapchan; + res = ioctl(zapfd, ZT_SPECIFY, &x); + if (res) { + fatal("Unable to specify channel %d: %s\n", zapchan, strerror(errno)); + close(zapfd); + zapfd = -1; + return -1; + } + } else + zapfd = STDIN_FILENO; + + + /* Get channel parameters */ + memset(&ztp, 0, sizeof(ztp)); + ztp.channo = -1; + + res = ioctl(zapfd, ZT_GET_PARAMS, &ztp); + + if (res) { + fatal("Device '%s' does not appear to be a zaptel device\n", devnam ? devnam : "<stdin>"); + } + + x = 1; + + /* Throw into HDLC/PPP mode */ + res = ioctl(zapfd, ZT_HDLCPPP, &x); + + if (res) { + fatal("Unable to put device '%s' into HDLC mode\n", devnam); + close(zapfd); + zapfd = -1; + return -1; + } + + /* Once the logging is fixed, print a message here indicating + connection parameters */ + zapchan = ztp.channo; + info("Connected to zaptel device '%s' (%d)\n", ztp.name, ztp.channo); + + return zapfd; +} + +static void disconnect_zaptel(void) +{ + int res; + int x = 0; + /* Throw out of HDLC mode */ + res = ioctl(zapfd, ZT_HDLCPPP, &x); + + if (res) { + warn("Unable to take device '%s' out of HDLC mode\n", devnam); + } + + /* Close if it's not stdin */ + if (strlen(devnam)) + close(zapfd); + warn("Disconnect from zaptel"); + +} + + +static int setspeed_zaptel(const char *cp) +{ + return 0; +} + +static void zaptel_extra_options() +{ + int ret; + char buf[256]; + snprintf(buf, 256, _PATH_ZAPOPT "%s",devnam); + if(!options_from_file(buf, 0, 0, 1)) + exit(EXIT_OPTION_ERROR); + +} + + + +static void send_config_zaptel(int mtu, + u_int32_t asyncmap, + int pcomp, + int accomp) +{ + int sock; + + if (mtu > ZAP_MTU) { + warn("Couldn't increase MTU to %d.", mtu); + mtu = ZAP_MTU; + } +} + + +static void recv_config_zaptel(int mru, + u_int32_t asyncmap, + int pcomp, + int accomp) +{ + if (mru > ZAP_MTU) + error("Couldn't increase MRU to %d", mru); +} + +static void set_xaccm_pppoe(int unit, ext_accm accm) +{ + /* NOTHING */ +} + + + +struct channel zaptel_channel; + +/* Check is cp is a valid zaptel device + * return either 1 if "cp" is a reasonable thing to name a device + * or die. + * 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 + */ + +int (*old_setdevname_hook)(const char* cp) = NULL; +int setdevname_zaptel(const char *cp) +{ + int ret; + int chan; + + /* If already set, forgoe */ + if (strlen(devnam)) + return 1; + + + if (strcmp(cp, "stdin")) { + ret = sscanf(cp, "%d", &chan); + if (ret != 1) { + fatal("Zaptel: Invalid channel: '%s'\n", cp); + return -1; + } + } + + strncpy(devnam, cp, sizeof(devnam) - 1); + + info("Using zaptel device '%s'\n", devnam); + + ret = 1; + + if( ret == 1 && the_channel != &zaptel_channel ){ + + the_channel = &zaptel_channel; + + { + char **a; + for (a = bad_options; *a != NULL; a++) + remove_option(*a); + } + modem = 0; + + lcp_allowoptions[0].neg_accompression = 0; + lcp_wantoptions[0].neg_accompression = 0; + + lcp_allowoptions[0].neg_pcompression = 0; + lcp_wantoptions[0].neg_pcompression = 0; + + ccp_allowoptions[0].deflate = 0 ; + ccp_wantoptions[0].deflate = 0 ; + + ipcp_allowoptions[0].neg_vj=0; + ipcp_wantoptions[0].neg_vj=0; + + ccp_allowoptions[0].bsd_compress = 0; + ccp_wantoptions[0].bsd_compress = 0; + + lcp_allowoptions[0].neg_asyncmap = 0; + lcp_wantoptions[0].neg_asyncmap = 0; + + } + return ret; +} + + + +void plugin_init(void) +{ + if (!ppp_available() && !new_style_driver) + fatal("Kernel doesn't support ppp_generic needed for Zaptel PPP"); + add_options(zaptel_options); + + info("Zaptel Plugin Initialized"); +} + +struct channel zaptel_channel = { + options: zaptel_options, + process_extra_options: &zaptel_extra_options, + check_options: NULL, + connect: &connect_zaptel, + disconnect: &disconnect_zaptel, + establish_ppp: &generic_establish_ppp, + disestablish_ppp: &generic_disestablish_ppp, + send_config: &send_config_zaptel, + recv_config: &recv_config_zaptel, + close: NULL, + cleanup: NULL +}; + |