diff --git a/ppp-2.4.2-pppoatm-make.patch b/ppp-2.4.2-pppoatm-make.patch new file mode 100644 index 0000000..7f46b9b --- /dev/null +++ b/ppp-2.4.2-pppoatm-make.patch @@ -0,0 +1,9 @@ +--- ppp-2.4.2/pppd/plugins/pppoatm/Makefile.linux.make 2004-10-04 11:37:28.331818344 +0100 ++++ ppp-2.4.2/pppd/plugins/pppoatm/Makefile.linux 2004-10-04 11:37:54.884781680 +0100 +@@ -1,5 +1,5 @@ + CC = gcc +-COPTS = -O2 -g ++COPTS = $(RPM_OPT_FLAGS) + CFLAGS = $(COPTS) -I../.. -I../../../include -fPIC + LDFLAGS = -shared + INSTALL = install -o root diff --git a/ppp-2.4.2-pppoatm.patch b/ppp-2.4.2-pppoatm.patch new file mode 100644 index 0000000..e3f869b --- /dev/null +++ b/ppp-2.4.2-pppoatm.patch @@ -0,0 +1,1214 @@ +--- ppp-2.4.2/pppd/plugins/Makefile.linux.pppoatm 2004-10-04 11:25:39.236617200 +0100 ++++ ppp-2.4.2/pppd/plugins/Makefile.linux 2004-10-04 11:26:31.945604216 +0100 +@@ -4,7 +4,7 @@ + LDFLAGS = -shared + INSTALL = install -o root + +-SUBDIRS := rp-pppoe ++SUBDIRS := rp-pppoe pppoatm + # Uncomment the next line to include the radius authentication plugin + # SUBDIRS += radius + PLUGINS := minconn.so passprompt.so passwordfd.so +--- /dev/null 2004-10-04 11:21:07.370511304 +0100 ++++ ppp-2.4.2/pppd/plugins/pppoatm/ans.c 2004-10-04 09:40:40.000000000 +0100 +@@ -0,0 +1,262 @@ ++/* ans.c - Interface for text2atm and atm2text to ANS */ ++ ++/* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */ ++ ++ ++/* ++ * This stuff is a temporary hack to avoid using gethostbyname_nsap and such ++ * without doing the "full upgrade" to getaddrinfo/getnameinfo. This also ++ * serves as an exercise for me to get all the details right before I propose ++ * a patch that would eventually end up in libc (and that should therefore be ++ * as stable as possible). ++ */ ++ ++#if HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "atm.h" ++#include "atmres.h" ++ ++ ++#define MAX_ANSWER 2048 ++#define MAX_NAME 1024 ++ ++#define MAX_LINE 2048 /* in /etc/e164_cc */ ++#define E164_CC_DEFAULT_LEN 2 ++#define E164_CC_FILE "/etc/e164_cc" ++ ++#define GET16(pos) (((pos)[0] << 8) | (pos)[1]) ++ ++ ++static int ans(const char *text,int wanted,void *result,int res_len) ++{ ++ unsigned char answer[MAX_ANSWER]; ++ unsigned char name[MAX_NAME]; ++ unsigned char *pos,*data,*found; ++ int answer_len,name_len,data_len,found_len; ++ int questions,answers; ++ ++ found_len = 0; /* gcc wants it */ ++ if ((answer_len = res_search(text,C_IN,wanted,answer,MAX_ANSWER)) < 0) ++ return TRY_OTHER; ++ /* ++ * Response header: id, flags, #queries, #answers, #authority, ++ * #additional (all 16 bits) ++ */ ++ pos = answer+12; ++ if (answer[3] & 15) return TRY_OTHER; /* rcode != 0 */ ++ questions = GET16(answer+4); ++ if (questions != 1) return TRY_OTHER; /* trouble ... */ ++ answers = GET16(answer+6); ++ if (answers < 1) return TRY_OTHER; ++ /* ++ * Query: name, type (16), class (16) ++ */ ++ if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME)) < 0) ++ return TRY_OTHER; ++ pos += name_len; ++ if (GET16(pos) != wanted || GET16(pos+2) != C_IN) return TRY_OTHER; ++ pos += 4; ++ /* ++ * Iterate over answers until we find something we like, giving priority ++ * to ATMA_AESA (until signaling is fixed to work with E.164 too) ++ */ ++ found = NULL; ++ while (answers--) { ++ /* ++ * RR: name, type (16), class (16), TTL (32), resource_len (16), ++ * resource_data ... ++ */ ++ if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME)) ++ < 0) return TRY_OTHER; ++ pos += name_len; ++ data_len = GET16(pos+8); ++ data = pos+10; ++ pos = data+data_len; ++ if (GET16(data-10) != wanted || GET16(data-8) != C_IN || !--data_len) ++ continue; ++ switch (wanted) { ++ case T_NSAP: ++ data_len++; ++ if (data_len != ATM_ESA_LEN) continue; ++ memcpy(((struct sockaddr_atmsvc *) result)-> ++ sas_addr.prv,data,ATM_ESA_LEN); ++ return 0; ++ case T_ATMA: ++ switch (*data++) { ++ case ATMA_AESA: ++ if (data_len != ATM_ESA_LEN) continue; ++ memcpy(((struct sockaddr_atmsvc *) result)-> ++ sas_addr.prv,data,ATM_ESA_LEN); ++ return 0; ++ case ATMA_E164: ++ if (data_len > ATM_E164_LEN) continue; ++ if (!found) { ++ found = data; ++ found_len = data_len; ++ } ++ break; ++ default: ++ continue; ++ } ++ case T_PTR: ++ if (dn_expand(answer,answer+answer_len,data,result, ++ res_len) < 0) return FATAL; ++ return 0; ++ default: ++ continue; ++ } ++ } ++ if (!found) return TRY_OTHER; ++ memcpy(((struct sockaddr_atmsvc *) result)->sas_addr.pub,found, ++ found_len); ++ ((struct sockaddr_atmsvc *) result)->sas_addr.pub[found_len] = 0; ++ return 0; ++} ++ ++ ++int ans_byname(const char *text,struct sockaddr_atmsvc *addr,int length, ++ int flags) ++{ ++ if (!(flags & T2A_SVC) || length != sizeof(*addr)) return TRY_OTHER; ++ memset(addr,0,sizeof(*addr)); ++ addr->sas_family = AF_ATMSVC; ++ if (!ans(text,T_ATMA,addr,length)) return 0; ++ return ans(text,T_NSAP,addr,length); ++} ++ ++ ++static int encode_nsap(char *buf,const unsigned char *addr) ++{ ++ static int fmt_dcc[] = { 2,12,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ++ 4,2,0 }; ++ static int fmt_e164[] = { 2,12,1,1,1,1,1,1,1,1,16,2,0 }; ++ int *fmt; ++ int pos,i,j; ++ ++ switch (*addr) { ++ case ATM_AFI_DCC: ++ case ATM_AFI_ICD: ++ case ATM_AFI_LOCAL: ++ case ATM_AFI_DCC_GROUP: ++ case ATM_AFI_ICD_GROUP: ++ case ATM_AFI_LOCAL_GROUP: ++ fmt = fmt_dcc; ++ break; ++ case ATM_AFI_E164: ++ case ATM_AFI_E164_GROUP: ++ fmt = fmt_e164; ++ break; ++ default: ++ return TRY_OTHER; ++ } ++ pos = 2*ATM_ESA_LEN; ++ for (i = 0; fmt[i]; i++) { ++ pos -= fmt[i]; ++ for (j = 0; j < fmt[i]; j++) ++ sprintf(buf++,"%x", ++ (addr[(pos+j) >> 1] >> 4*(1-((pos+j) & 1))) & 0xf); ++ *buf++ = '.'; ++ } ++ strcpy(buf,"AESA.ATMA.INT."); ++ return 0; ++} ++ ++ ++static int encode_nsap_new(char *buf,const unsigned char *addr) ++{ ++ int i; ++ int digit; ++ ++ for (i = 20; i; ) { ++ i--; ++ digit = addr[i] & 0x0F; ++ *(buf++) = digit + (digit >= 10 ? '7' : '0'); ++ *(buf++) = '.'; ++ digit = ((unsigned char) (addr[i])) >> 4; ++ *(buf++) = digit + (digit >= 10 ? '7' : '0'); ++ *(buf++) = '.'; ++ } ++ strcpy (buf, "NSAP.INT."); ++ return 0; ++} ++ ++ ++static int cc_len(int p0,int p1) ++{ ++ static char *cc_table = NULL; ++ FILE *file; ++ char buffer[MAX_LINE]; ++ char *here; ++ int cc; ++ ++ if (!cc_table) { ++ if (!(cc_table = malloc(100))) { ++ perror("malloc"); ++ return E164_CC_DEFAULT_LEN; ++ } ++ memset(cc_table,E164_CC_DEFAULT_LEN,100); ++ if (!(file = fopen(E164_CC_FILE,"r"))) ++ perror(E164_CC_FILE); ++ else { ++ while (fgets(buffer,MAX_LINE,file)) { ++ here = strchr(buffer,'#'); ++ if (here) *here = 0; ++ if (sscanf(buffer,"%d",&cc) == 1) { ++ if (cc < 10) cc_table[cc] = 1; ++ else if (cc < 100) cc_table[cc] = 2; ++ else cc_table[cc/10] = 3; ++ } ++ } ++ fclose(file); ++ } ++ } ++ if (cc_table[p0] == 1) return 1; ++ return cc_table[p0*10+p1]; ++} ++ ++ ++static int encode_e164(char *buf,const char *addr) ++{ ++ const char *prefix,*here; ++ ++ prefix = addr+cc_len(addr[0]-48,addr[1]-48); ++ here = strchr(addr,0); ++ while (here > prefix) { ++ *buf++ = *--here; ++ *buf++ = '.'; ++ } ++ while (here > addr) *buf++ = *addr++; ++ strcpy(buf,".E164.ATMA.INT."); ++ return 0; ++} ++ ++ ++int ans_byaddr(char *buffer,int length,const struct sockaddr_atmsvc *addr, ++ int flags) ++{ ++ char tmp[MAX_NAME]; /* could be smaller ... */ ++ int res; ++ ++ if (addr->sas_addr.prv) { ++ res = encode_nsap(tmp,addr->sas_addr.prv); ++ if (!res && !ans(tmp,T_PTR,buffer,length)) return 0; ++ res = encode_nsap_new(tmp,addr->sas_addr.prv); ++ if (res < 0) return res; ++ return ans(tmp,T_PTR,buffer,length); ++ } else { ++ res = encode_e164(tmp,addr->sas_addr.pub); ++ if (res < 0) return res; ++ return ans(tmp,T_PTR,buffer,length); ++ } ++} +--- /dev/null 2004-10-04 11:21:07.370511304 +0100 ++++ ppp-2.4.2/pppd/plugins/pppoatm/atm.h 2004-10-04 09:36:25.000000000 +0100 +@@ -0,0 +1,126 @@ ++/* atm.h - Functions useful for ATM applications */ ++ ++/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ ++ ++ ++#ifndef _ATM_H ++#define _ATM_H ++ ++#include ++#include ++#include ++ ++/* Some stuff omitted by Fedora glibc-kernheaders */ ++static __inline__ int atmsvc_addr_in_use(struct sockaddr_atmsvc addr) ++{ ++ return *addr.sas_addr.prv || *addr.sas_addr.pub; ++} ++ ++static __inline__ int atmpvc_addr_in_use(struct sockaddr_atmpvc addr) ++{ ++ return addr.sap_addr.itf || addr.sap_addr.vpi || addr.sap_addr.vci; ++} ++ ++struct atmif_sioc { ++ int number; ++ int length; ++ void *arg; ++}; ++ ++typedef unsigned short atm_backend_t; ++ ++/* ++ * For versions of glibc < 2.1 ++ */ ++ ++#ifndef AF_ATMPVC ++#define AF_ATMPVC 8 ++#endif ++ ++#ifndef AF_ATMSVC ++#define AF_ATMSVC 20 ++#endif ++ ++#ifndef PF_ATMPVC ++#define PF_ATMPVC AF_ATMPVC ++#endif ++ ++#ifndef PF_ATMSVC ++#define PF_ATMSVC AF_ATMSVC ++#endif ++ ++#ifndef SOL_ATM ++#define SOL_ATM 264 ++#endif ++ ++#ifndef SOL_AAL ++#define SOL_AAL 265 ++#endif ++ ++ ++#define HOSTS_ATM "/etc/hosts.atm" ++ ++/* text2atm flags */ ++#define T2A_PVC 1 /* address is PVC */ ++#define T2A_SVC 2 /* address is SVC */ ++#define T2A_UNSPEC 4 /* allow unspecified parts in PVC address */ ++#define T2A_WILDCARD 8 /* allow wildcards in PVC or SVC address */ ++#define T2A_NNI 16 /* allow NNI VPI range (PVC) */ ++#define T2A_NAME 32 /* allow name resolution */ ++#define T2A_REMOTE 64 /* OBSOLETE */ ++#define T2A_LOCAL 128 /* don't use ANS */ ++ ++/* atm2text flags */ ++#define A2T_PRETTY 1 /* add syntactic sugar */ ++#define A2T_NAME 2 /* attempt name lookup */ ++#define A2T_REMOTE 4 /* OBSOLETE */ ++#define A2T_LOCAL 8 /* don't use ANS */ ++ ++/* atm_equal flags */ ++#define AXE_WILDCARD 1 /* allow wildcard match */ ++#define AXE_PRVOPT 2 /* private part of SVC address is optional */ ++ ++/* text2qos flags */ ++#define T2Q_DEFAULTS 1 /* structure contains default values */ ++ ++/* text2sap flags */ ++#define T2S_NAME 1 /* attempt name lookup */ ++#define T2S_LOCAL 2 /* we may support NIS or such in the future */ ++ ++/* sap2text flags */ ++#define S2T_NAME 1 /* attempt name lookup */ ++#define S2T_LOCAL 2 /* we may support NIS or such in the future */ ++ ++/* sap_equal flags */ ++#define SXE_COMPATIBLE 1 /* check for compatibility instead of identity*/ ++#define SXE_NEGOTIATION 2 /* allow negotiation; requires SXE_COMPATIBLE; ++ assumes "a" defines the available ++ capabilities */ ++#define SXE_RESULT 4 /* return selected SAP */ ++ ++#define MAX_ATM_ADDR_LEN (2*ATM_ESA_LEN+ATM_E164_LEN+5) ++ /* 4 dots, 1 plus */ ++#define MAX_ATM_NAME_LEN 256 /* wild guess */ ++#define MAX_ATM_QOS_LEN 116 /* 5+4+2*(3+3*(7+9)+2)+1 */ ++#define MAX_ATM_SAP_LEN 255 /* BHLI(27)+1+3*BLLI(L2=33,L3=41,+1)+2 */ ++ ++ ++int text2atm(const char *text,struct sockaddr *addr,int length,int flags); ++int atm2text(char *buffer,int length,const struct sockaddr *addr,int flags); ++int atm_equal(const struct sockaddr *a,const struct sockaddr *b,int len, ++ int flags); ++ ++int sdu2cell(int s,int sizes,const int *sdu_size,int *num_sdu); ++ ++int text2qos(const char *text,struct atm_qos *qos,int flags); ++int qos2text(char *buffer,int length,const struct atm_qos *qos,int flags); ++int qos_equal(const struct atm_qos *a,const struct atm_qos *b); ++ ++int text2sap(const char *text,struct atm_sap *sap,int flags); ++int sap2text(char *buffer,int length,const struct atm_sap *sap,int flags); ++int sap_equal(const struct atm_sap *a,const struct atm_sap *b,int flags,...); ++ ++int __t2q_get_rate(const char **text,int up); ++int __atmlib_fetch(const char **pos,...); /* internal use only */ ++ ++#endif +--- /dev/null 2004-10-04 11:21:07.370511304 +0100 ++++ ppp-2.4.2/pppd/plugins/pppoatm/atmres.h 2004-10-04 09:36:46.000000000 +0100 +@@ -0,0 +1,36 @@ ++/* atmres.h - Common definitions and prototypes for resolver functions */ ++ ++/* Written 1996,1998 by Werner Almesberger, EPFL-LRC/ICA */ ++ ++ ++#ifndef _ATMRES_H ++#define _ATMRES_H ++ ++#include ++#include ++ ++ ++/* Some #defines that may be needed if ANS isn't installed on that system */ ++ ++#ifndef T_ATMA ++#define T_ATMA 34 ++#endif ++#ifndef ATMA_AESA ++#define ATMA_AESA 0 ++#endif ++#ifndef ATMA_E164 ++#define ATMA_E164 1 ++#endif ++ ++/* Return codes for text2atm and atm2text */ ++ ++#define TRY_OTHER -2 ++#define FATAL -1 /* must be -1 */ ++ ++ ++int ans_byname(const char *text,struct sockaddr_atmsvc *addr,int length, ++ int flags); ++int ans_byaddr(char *buffer,int length,const struct sockaddr_atmsvc *addr, ++ int flags); ++ ++#endif +--- /dev/null 2004-10-04 11:21:07.370511304 +0100 ++++ ppp-2.4.2/pppd/plugins/pppoatm/Makefile.linux 2004-10-04 11:32:03.221242664 +0100 +@@ -0,0 +1,40 @@ ++CC = gcc ++COPTS = -O2 -g ++CFLAGS = $(COPTS) -I../.. -I../../../include -fPIC ++LDFLAGS = -shared ++INSTALL = install -o root ++ ++#*********************************************************************** ++ ++PLUGIN := pppoatm.so ++PLUGIN_OBJS := pppoatm.o ++ ++#******* ++# Do we have the ATM libraries installed? Set HAVE_LIBATM to use them, ++# or leave it unset to build the few routines we actually _use_ into ++# the plugin directly. ++# ++#HAVE_LIBATM=yes ++ ++ifdef HAVE_LIBATM ++LIBATM := -latm ++else ++CFLAGS += -I. ++PLUGIN_OBJS += text2qos.o text2atm.o misc.o ans.o ++endif ++ ++#********* ++all: $(PLUGIN) ++ ++$(PLUGIN): $(PLUGIN_OBJS) ++ $(CC) $(CFLAGS) -o $@ -shared $^ $(LIBATM) ++ ++install: all ++ $(INSTALL) -d -m 755 $(LIBDIR) ++ $(INSTALL) -c -m 4550 $(PLUGIN) $(LIBDIR) ++ ++clean: ++ rm -f *.o *.so ++ ++%.o: %.c ++ $(CC) $(CFLAGS) -c -o $@ $< +--- /dev/null 2004-10-04 11:21:07.370511304 +0100 ++++ ppp-2.4.2/pppd/plugins/pppoatm/misc.c 2004-10-04 09:25:39.000000000 +0100 +@@ -0,0 +1,51 @@ ++/* misc.c - Miscellaneous library functions */ ++ ++/* Written 1997-2000 by Werner Almesberger, EPFL-ICA/ICA */ ++ ++#if HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include /* for htons */ ++ ++#include ++#include ++ ++ ++int __atmlib_fetch(const char **pos,...) ++{ ++ const char *value; ++ int ref_len,best_len,len; ++ int i,best; ++ va_list ap; ++ ++ va_start(ap,pos); ++ ref_len = strlen(*pos); ++ best_len = 0; ++ best = -1; ++ for (i = 0; (value = va_arg(ap,const char *)); i++) { ++ len = strlen(value); ++ if (*value != '!' && len <= ref_len && len > best_len && ++ !strncasecmp(*pos,value,len)) { ++ best = i; ++ best_len = len; ++ } ++ } ++ va_end(ap); ++ if (best > -1) (*pos) += best_len; ++ return best; ++} ++ ++ ++void atm_tcpip_port_mapping(char *vs_id,uint8_t protocol,uint16_t port) ++{ ++ memcpy(vs_id,ATM_FORUM_OUI "\x01",4); ++ vs_id[4] = protocol; /* e.g. IP_TCP or IP_UDP; from netinet/protocols.h */ ++ vs_id[5] = (htons(port) >> 8) & 255; ++ vs_id[6] = htons(port) & 255; ++} +--- /dev/null 2004-10-04 11:21:07.370511304 +0100 ++++ ppp-2.4.2/pppd/plugins/pppoatm/pppoatm.c 2004-10-04 09:26:01.000000000 +0100 +@@ -0,0 +1,224 @@ ++/* 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 ++ * ++ * Updated to ppp-2.4.2 by David Woodhouse 2004. ++ * - disconnect method added ++ * - remove_options() abuse removed. ++ * ++ * 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 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 int pppoa_fd = -1; ++ ++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}, ++ { "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) { ++ the_channel = &pppoa_channel; ++ 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)); ++ pppoa_fd = fd; ++ return fd; ++} ++ ++static void disconnect_pppoatm(void) ++{ ++ close(pppoa_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: &disconnect_pppoatm, ++ establish_ppp: &generic_establish_ppp, ++ disestablish_ppp: &generic_disestablish_ppp, ++ send_config: &send_config_pppoa, ++ recv_config: &recv_config_pppoa, ++ close: NULL, ++ cleanup: NULL ++}; +--- /dev/null 2004-10-04 11:21:07.370511304 +0100 ++++ ppp-2.4.2/pppd/plugins/pppoatm/text2atm.c 2004-10-04 09:25:50.000000000 +0100 +@@ -0,0 +1,249 @@ ++/* text2atm.c - Converts textual representation of ATM address to binary ++ encoding */ ++ ++/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ ++ ++#if HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++ ++#include "atm.h" ++#include "atmsap.h" ++#include "atmres.h" ++ ++ ++static int try_pvc(const char *text,struct sockaddr_atmpvc *addr,int flags) ++{ ++ int part[3]; ++ int i; ++ ++ part[0] = part[1] = part[2] = 0; ++ i = 0; ++ while (1) { ++ if (!*text) return FATAL; /* empty or ends with a dot */ ++ if (i == 3) return TRY_OTHER; /* too long */ ++ if (isdigit(*text)) { ++ if (*text == '0' && isdigit(text[1])) return TRY_OTHER; ++ /* no leading zeroes */ ++ do { ++ if (part[i] > INT_MAX/10) return TRY_OTHER;/* number too big */ ++ part[i] = part[i]*10+*text++-'0'; ++ } ++ while (isdigit(*text)); ++ i++; ++ if (!*text) break; ++ if (*text++ != '.') return TRY_OTHER; /* non-PVC character */ ++ continue; ++ } ++ if (*text == '*') { ++ if (!(flags & T2A_WILDCARD)) return FATAL; /* not allowed */ ++ part[i++] = ATM_ITF_ANY; /* all *_ANY have the same value */ ++ } ++ else { ++ if (*text != '?') return TRY_OTHER; /* invalid character */ ++ if (!(flags & T2A_UNSPEC)) return FATAL; /* not allowed */ ++ part[i++] = ATM_VPI_UNSPEC; /* all *_UNSPEC have the same ++ value */ ++ } ++ if (!*++text) break; ++ if (*text++ != '.') return FATAL; /* dot required */ ++ } ++ if (i < 2) return TRY_OTHER; /* no dots */ ++ if (i == 2) { ++ part[2] = part[1]; ++ part[1] = part[0]; ++ part[0] = 0; /* default interface */ ++ } ++ if (part[0] > SHRT_MAX || part[2] > ATM_MAX_VCI) ++ return TRY_OTHER; /* too big */ ++ if (part[1] > (flags & T2A_NNI ? ATM_MAX_VPI_NNI : ATM_MAX_VPI)) ++ return TRY_OTHER; /* too big */ ++ if (part[0] == ATM_VPI_UNSPEC) return FATAL; /* bad */ ++ addr->sap_family = AF_ATMPVC; ++ addr->sap_addr.itf = part[0]; ++ addr->sap_addr.vpi = part[1]; ++ addr->sap_addr.vci = part[2]; ++ return 0; ++} ++ ++ ++static int do_try_nsap(const char *text,struct sockaddr_atmsvc *addr,int flags) ++{ ++ const char *walk; ++ int count,pos,dot; ++ int offset,len; ++ char value; ++ ++ count = dot = 0; ++ for (walk = text; *walk; walk++) ++ if (isdigit(*walk)) { ++ if (count++ == 15) break; ++ dot = 1; ++ } ++ else if (*text != '.') break; ++ else if (!dot) return FATAL; /* two dots in a row */ ++ else dot = 0; ++ if (*walk != ':') { ++ pos = 0; ++ offset = 0; ++ } ++ else { ++ if (!dot || *text == '0') return FATAL; ++ addr->sas_addr.prv[0] = ATM_AFI_E164; ++ addr->sas_addr.prv[1] = 0; ++ memset(addr->sas_addr.prv+1,0,8); ++ for (pos = 18-count-1; *text; text++) { ++ if (*text == '.') continue; ++ if (*text == ':') break; ++ else { ++ if (pos & 1) addr->sas_addr.prv[pos >> 1] |= *text-'0'; ++ else addr->sas_addr.prv[pos >> 1] = (*text-'0') << 4; ++ pos++; ++ } ++ } ++ addr->sas_addr.prv[8] |= 0xf; ++ text++; ++ pos++; ++ offset = 72; ++ } ++ for (dot = 0; *text; text++) ++ if (isxdigit(*text)) { ++ if (pos == ATM_ESA_LEN*2) return TRY_OTHER; /* too long */ ++ value = isdigit(*text) ? *text-'0' : (islower(*text) ? ++ toupper(*text) : *text)-'A'+10; ++ if (pos & 1) addr->sas_addr.prv[pos >> 1] |= value; ++ else addr->sas_addr.prv[pos >> 1] = value << 4; ++ pos++; ++ dot = 1; ++ } ++ else ++ if (*text == '/' && (flags & T2A_WILDCARD)) break; ++ else if (*text != '.') return TRY_OTHER; ++ else { ++ if (!dot) return FATAL; /* two dots in a row */ ++ dot = 0; ++ } ++ if (!dot) return FATAL; ++ if (pos > 1 && !*addr->sas_addr.prv) ++ return TRY_OTHER; /* no leading zeroes */ ++ if (!*text) ++ return pos != ATM_ESA_LEN*2 ? TRY_OTHER : ATM_ESA_LEN*2; ++ /* handle bad length */ ++ len = 0; ++ while (*++text) { ++ if (!isdigit(*text)) return -1; /* non-digit in length */ ++ if (len >= pos*4) return -1; /* too long */ ++ len = len*10+*text-'0'; ++ } ++ if (len > 7 && addr->sas_addr.prv[0] != ATM_AFI_E164) offset = 72; ++ if (len < offset) return FATAL; ++ return len > pos*4 ? TRY_OTHER : len; ++} ++ ++ ++static int try_nsap(const char *text,struct sockaddr_atmsvc *addr,int flags) ++{ ++ int result; ++ ++ result = do_try_nsap(text,addr,flags); ++ if (result < 0) return result; ++ addr->sas_family = AF_ATMSVC; ++ *addr->sas_addr.pub = 0; ++ return result; ++} ++ ++ ++static int try_e164(const char *text,struct sockaddr_atmsvc *addr,int flags) ++{ ++ int i,dot,result; ++ ++ if (*text == ':' || *text == '+') text++; ++ for (i = dot = 0; *text; text++) ++ if (isdigit(*text)) { ++ if (i == ATM_E164_LEN) return TRY_OTHER; /* too long */ ++ addr->sas_addr.pub[i++] = *text; ++ dot = 1; ++ } ++ else if (*text != '.') break; ++ else { ++ if (!dot) return TRY_OTHER; /* two dots in a row */ ++ dot = 0; ++ } ++ if (!dot) return TRY_OTHER; ++ addr->sas_addr.pub[i] = 0; ++ *addr->sas_addr.prv = 0; ++ result = 0; ++ if (*text) { ++ if (*text++ != '+') return TRY_OTHER; ++ else { ++ result = do_try_nsap(text,addr,flags); ++ if (result < 0) return FATAL; ++ } ++ } ++ addr->sas_family = AF_ATMSVC; ++ return result; ++} ++ ++ ++static int search(FILE *file,const char *text,struct sockaddr *addr,int length, ++ int flags) ++{ ++ char line[MAX_ATM_NAME_LEN+1]; ++ const char *here; ++ int result; ++ ++ while (fgets(line,MAX_ATM_NAME_LEN,file)) { ++ if (!strtok(line,"\t\n ")) continue; ++ while ((here = strtok(NULL,"\t\n "))) ++ if (!strcasecmp(here,text)) { ++ here = strtok(line,"\t\n "); ++ result = text2atm(here,addr,length,flags); ++ if (result >= 0) return result; ++ } ++ } ++ return TRY_OTHER; ++} ++ ++ ++static int try_name(const char *text,struct sockaddr *addr,int length, ++ int flags) ++{ ++ FILE *file; ++ int result; ++ ++ if (!(file = fopen(HOSTS_ATM,"r"))) return TRY_OTHER; ++ result = search(file,text,addr,length,flags); ++ (void) fclose(file); ++ return result; ++} ++ ++ ++int text2atm(const char *text,struct sockaddr *addr,int length,int flags) ++{ ++ int result; ++ ++ if (!*text) return -1; ++ if (!(flags & (T2A_PVC | T2A_SVC))) flags |= T2A_PVC | T2A_SVC; ++ if (length < sizeof(struct sockaddr_atmpvc)) return -1; ++ if (flags & T2A_PVC) { ++ result = try_pvc(text,(struct sockaddr_atmpvc *) addr,flags); ++ if (result != TRY_OTHER) return result; ++ } ++ if ((flags & T2A_SVC) && length >= sizeof(struct sockaddr_atmsvc)) { ++ result = try_nsap(text,(struct sockaddr_atmsvc *) addr,flags); ++ if (result != TRY_OTHER) return result; ++ result = try_e164(text,(struct sockaddr_atmsvc *) addr,flags); ++ if (result != TRY_OTHER) return result; ++ } ++ if (!(flags & T2A_NAME)) return -1; ++ result = try_name(text,addr,length,flags & ~T2A_NAME); ++ if (result == TRY_OTHER && !(flags & T2A_LOCAL)) ++ result = ans_byname(text,(struct sockaddr_atmsvc *) addr,length,flags); ++ if (result != TRY_OTHER) return result; ++ return -1; ++} +--- /dev/null 2004-10-04 11:21:07.370511304 +0100 ++++ ppp-2.4.2/pppd/plugins/pppoatm/text2qos.c 2004-10-04 09:25:46.000000000 +0100 +@@ -0,0 +1,180 @@ ++/* text2qos.c - Converts textual representation of QOS parameters to binary ++ encoding */ ++ ++/* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */ ++ ++#if HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "atm.h" ++ ++ ++#define fetch __atmlib_fetch ++ ++ ++#define RATE_ERROR -2 ++ ++ ++int __t2q_get_rate(const char **text,int up) ++{ ++ const char mult[] = "kKmMgGg"; ++ const char *multiplier; ++ char *end; ++ unsigned int rate,fract; ++ int power; ++ ++ if (!strncmp(*text,"max",3)) { ++ *text += 3; ++ return ATM_MAX_PCR; ++ } ++ rate = strtoul(*text,&end,10); ++ power = fract = 0; ++ if (*end == '.') ++ for (end++; *end && isdigit(*end); end++) { ++ fract = fract*10+*end-48; ++ if (--power == -9) break; ++ } ++ multiplier = NULL; ++ if (*end && (multiplier = strchr(mult,*end))) { ++ while (multiplier >= mult) { ++ if (rate > UINT_MAX/1000) return RATE_ERROR; ++ rate *= 1000; ++ power += 3; ++ multiplier -= 2; ++ } ++ end++; ++ } ++ while (power && fract) ++ if (power < 0) { ++ fract /= 10; ++ power++; ++ } ++ else { ++ fract *= 10; ++ power--; ++ } ++ rate += fract; ++ if (strlen(end) < 3) { ++ if (multiplier) return RATE_ERROR; ++ } ++ else if (!strncmp(end,"cps",3)) end += 3; ++ else if (!strncmp(end,"bps",3)) { ++ rate = (rate+(up ? 8*ATM_CELL_PAYLOAD-1 : 0))/8/ ++ ATM_CELL_PAYLOAD; ++ end += 3; ++ } ++ else if (multiplier) return RATE_ERROR; ++ if (rate > INT_MAX) return RATE_ERROR; ++ *text = end; ++ return rate; ++} ++ ++ ++static int params(const char **text,struct atm_trafprm *a, ++ struct atm_trafprm *b) ++{ ++ int value; ++ char *end; ++ ++ if (*(*text)++ != ':') return -1; ++ while (1) { ++ if (!**text) return -1; ++ switch (fetch(text,"max_pcr=","pcr=","min_pcr=","max_sdu=","sdu=", ++ NULL)) { ++ case 0: ++ if ((value = __t2q_get_rate(text,0)) == RATE_ERROR) return -1; ++ if (a) a->max_pcr = value; ++ if (b) b->max_pcr = value; ++ break; ++ case 1: ++ if ((value = __t2q_get_rate(text,0)) == RATE_ERROR) return -1; ++ if (a) a->pcr = value; ++ if (b) b->pcr = value; ++ break; ++ case 2: ++ if ((value = __t2q_get_rate(text,1)) == RATE_ERROR) return -1; ++ if (value == ATM_MAX_PCR) return -1; ++ if (a) a->min_pcr = value; ++ if (b) b->min_pcr = value; ++ break; ++ case 3: ++ case 4: ++ value = strtol(*text,&end,10); ++ if (value < 0) return -1; ++ *text = end; ++ if (a) a->max_sdu = value; ++ if (b) b->max_sdu = value; ++ break; ++ default: ++ return 0; ++ } ++ if (!**text) break; ++ if (*(*text)++ != ',') return -1; ++ } ++ return 0; ++} ++ ++ ++int text2qos(const char *text,struct atm_qos *qos,int flags) ++{ ++ int traffic_class,aal; ++ ++ traffic_class = ATM_NONE; ++ aal = ATM_NO_AAL; ++ do { ++ static const unsigned char aal_number[] = { ATM_AAL0, ATM_AAL5 }; ++ int item; ++ ++ item = fetch(&text,"!none","ubr","cbr","vbr","abr","aal0","aal5",NULL); ++ switch (item) { ++ case 1: ++ case 2: ++ /* we don't support VBR yet */ ++ case 4: ++ traffic_class = item; ++ break; ++ case 5: ++ case 6: ++ aal = aal_number[item-5]; ++ break; ++ default: ++ return -1; ++ } ++ } ++ while (*text == ',' ? text++ : 0); ++ if (!traffic_class) return -1; ++ if (qos && !(flags & T2Q_DEFAULTS)) memset(qos,0,sizeof(*qos)); ++ if (qos) qos->txtp.traffic_class = qos->rxtp.traffic_class = traffic_class; ++ if (qos && aal) qos->aal = aal; ++ if (!*text) return 0; ++ if (params(&text,qos ? &qos->txtp : NULL,qos ? &qos->rxtp : NULL)) ++ return -1; ++ if (!*text) return 0; ++ switch (fetch(&text,"tx","rx",NULL)) { ++ case 0: ++ if (!fetch(&text,":none",NULL)) { ++ if (qos) qos->txtp.traffic_class = ATM_NONE; ++ if (*text == ',') text++; ++ break; ++ } ++ if (params(&text,qos ? &qos->txtp : NULL,NULL)) return -1; ++ break; ++ case 1: ++ text -= 2; ++ break; ++ default: ++ return -1; ++ } ++ if (!*text) return 0; ++ if (fetch(&text,"rx",NULL)) return -1; ++ if (!fetch(&text,":none",NULL) && qos) qos->rxtp.traffic_class = ATM_NONE; ++ else if (params(&text,qos ? &qos->rxtp : NULL,NULL)) return -1; ++ return *text ? -1 : 0; ++} +--- ppp-2.4.2/configure.pppoatm 2004-10-04 11:44:37.925510176 +0100 ++++ ppp-2.4.2/configure 2004-10-04 11:45:03.575610768 +0100 +@@ -141,7 +141,7 @@ + rm -f Makedefs.com + ln -s $ksrc/Makedefs$compiletype Makedefs.com + echo " $ksrc/Makedefs$compiletype -> Makedefs.com" +- for dir in pppd pppstats chat pppdump pppd/plugins pppd/plugins/rp-pppoe pppd/plugins/radius; do ++ for dir in pppd pppstats chat pppdump pppd/plugins pppd/plugins/rp-pppoe pppd/plugins/radius pppd/plugins/pppoatm; do + rm -f $dir/Makefile + if [ -f $dir/Makefile.$makext ]; then + ln -s Makefile.$makext $dir/Makefile diff --git a/ppp.spec b/ppp.spec index bdd8815..87e62d7 100644 --- a/ppp.spec +++ b/ppp.spec @@ -1,7 +1,7 @@ Summary: The PPP (Point-to-Point Protocol) daemon. Name: ppp Version: 2.4.2 -Release: 5.1 +Release: 6 License: distributable Group: System Environment/Daemons Source0: ftp://ftp.samba.org/pub/ppp/ppp-%{version}.tar.gz @@ -22,6 +22,8 @@ Patch11: ppp-2.4.2-change_resolv_conf.patch Patch12: ppp-2.4.2-pcap.patch Patch13: ppp-2.4.2-no_strip.patch Patch14: ppp-2.4.2-argv.patch +Patch15: ppp-2.4.2-pppoatm.patch +Patch16: ppp-2.4.2-pppoatm-make.patch BuildRoot: %{_tmppath}/%{name}-root BuildPrereq: pam-devel, libpcap @@ -53,6 +55,9 @@ organization over a modem and phone line. %patch12 -p1 -b .pcap %patch13 -p1 -b .no_strip %patch14 -p1 -b .argv +%patch15 -p1 -b .atm1 +%patch16 -p1 -b .atm2 + find . -type f -name "*.sample" | xargs rm -f @@ -108,7 +113,11 @@ rm -rf $RPM_BUILD_ROOT %config /etc/logrotate.d/ppp %doc FAQ PLUGINS README README.cbcp README.linux README.MPPE README.MSCHAP80 README.MSCHAP81 README.pwfd README.pppoe scripts sample + %changelog +* Mon Oct 4 2004 David Woodhouse 2.4.2-6 +- Add pppoatm plugin (#131555) + * Thu Sep 16 2004 Thomas Woerner 2.4.2-5.1 - fixed subscript out of range (#132677)