]> git.pld-linux.org Git - packages/ppp.git/commitdiff
ugh
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Sun, 10 Jun 2001 21:18:15 +0000 (21:18 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    ppp-2.4.1-pppoe.patch2 -> 1.2

ppp-2.4.1-pppoe.patch2 [deleted file]

diff --git a/ppp-2.4.1-pppoe.patch2 b/ppp-2.4.1-pppoe.patch2
deleted file mode 100644 (file)
index 449489f..0000000
+++ /dev/null
@@ -1,3679 +0,0 @@
-diff -r -N -u -b -B ppp-2.4.1.orig/configure ppp-2.4.1.pppoe2/configure
---- ppp-2.4.1.orig/configure   Mon Apr 24 03:41:40 2000
-+++ ppp-2.4.1.pppoe2/configure Fri Mar 30 16:37:20 2001
-@@ -131,7 +131,7 @@
-       makext=$orig_makext 
-     fi
-   fi
--  for dir in pppd pppstats chat pppdump; do
-+  for dir in pppd pppstats chat pppdump pppd/plugins pppd/plugins/pppoe; do
-     rm -f $dir/Makefile
-     if [ -f $dir/Makefile.$makext ]; then
-       ln -s Makefile.$makext $dir/Makefile
-diff -r -N -u -b -B ppp-2.4.1.orig/linux/Makefile.top ppp-2.4.1.pppoe2/linux/Makefile.top
---- ppp-2.4.1.orig/linux/Makefile.top  Mon Apr 17 06:39:26 2000
-+++ ppp-2.4.1.pppoe2/linux/Makefile.top        Fri Mar 30 18:43:51 2001
-@@ -10,6 +10,7 @@
- all:
-       cd chat; $(MAKE) $(MFLAGS) all
-+      cd pppd/plugins; $(MAKE) $(MFLAGS) all
-       cd pppd; $(MAKE) $(MFLAGS) all
-       cd pppstats; $(MAKE) $(MFLAGS) all
-       cd pppdump; $(MAKE) $(MFLAGS) all
-@@ -18,6 +19,7 @@
- install-progs:
-       cd chat; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
-+      cd pppd/plugins; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
-       cd pppd; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
-       cd pppstats; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
-       cd pppdump; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
-@@ -44,6 +46,7 @@
-       rm -f `find . -name 'core' -print`
-       rm -f `find . -name '*~' -print`
-       cd chat; $(MAKE) clean
-+      cd pppd/plugins; $(MAKE) clean
-       cd pppd; $(MAKE) clean
-       cd pppstats; $(MAKE) clean
-       cd pppdump; $(MAKE) clean
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/options.c ppp-2.4.1.pppoe2/pppd/options.c
---- ppp-2.4.1.orig/pppd/options.c      Tue Mar 13 00:56:19 2001
-+++ ppp-2.4.1.pppoe2/pppd/options.c    Fri Mar 30 19:33:55 2001
-@@ -789,6 +789,23 @@
- }
- /*
-+ * 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(name)
-+    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 -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/Makefile.linux ppp-2.4.1.pppoe2/pppd/plugins/Makefile.linux
---- ppp-2.4.1.orig/pppd/plugins/Makefile.linux Tue Mar  6 23:21:18 2001
-+++ ppp-2.4.1.pppoe2/pppd/plugins/Makefile.linux       Sun May 27 08:08:58 2001
-@@ -3,7 +3,10 @@
- LDFLAGS       = -shared
- INSTALL       = install
--all:  minconn.so passprompt.so
-+all:  minconn.so passprompt.so pppoe/pppoe.so
-+
-+pppoe/pppoe.so:
-+      $(MAKE) -C pppoe $(MFLAGS) pppoe.so
- minconn.so: minconn.c
-       $(CC) -o $@ $(LDFLAGS) $(CFLAGS) minconn.c
-@@ -13,7 +16,10 @@
- LIBDIR        = /usr/lib/pppd
--install: minconn.so passprompt.so
-+install: minconn.so passprompt.so pppoe/pppoe.so
-       version=`awk -F '"' '/VERSION/ { print $$2; }' ../patchlevel.h`; \
-       $(INSTALL) -d $(LIBDIR)/$$version; \
-       $(INSTALL) $? $(LIBDIR)/$$version
-\ No newline at end of file
-+
-+clean:
-+      rm -rf *.o *.so
-\ No newline at end of file
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/Makefile.linux ppp-2.4.1.pppoe2/pppd/plugins/pppoe/Makefile.linux
---- ppp-2.4.1.orig/pppd/plugins/pppoe/Makefile.linux   Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/Makefile.linux Sun May 27 08:08:40 2001
-@@ -0,0 +1,43 @@
-+CC    = gcc
-+CFLAGS        = -g  -I.. -I../.. -I../../../include -D_linux_=1 -fPIC
-+LDFLAGS       = -shared
-+
-+all: pppoe.so pppoed
-+
-+
-+PLUGINDIR = $(LIBDIR)/plugins
-+PLUGINSRCS= pppoe.c libpppoe.c utils.c pppoehash.c pppoe_client.c \
-+              pppoe_relay.c pppoe_server.c pppd_utils.c
-+#
-+# include dependancies if present and backup if as a header file
-+ifeq (.depend,$(wildcard .depend))
-+include .depend
-+endif
-+
-+
-+
-+pppoefwd: pppoefwd.o libpppoe.a 
-+      $(CC) -o $@ $^
-+
-+pppoed: pppoed.o pppd_utils.o libpppoe.a 
-+      $(CC) -o $@ $^
-+
-+libpppoe.a: pppoehash.o pppoe_client.o pppoe_relay.o pppoe_server.o \
-+      utils.o libpppoe.o 
-+      ar -rc $@ $^
-+
-+pppoe.so: pppoe.o libpppoe.a
-+      $(CC) -o $@ $(LDFLAGS) $^
-+
-+%.so: %.c
-+      $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^
-+
-+clean: 
-+      rm -f *.o *.so *.a pppoefwd pppoed
-+
-+
-+$(PLUGINDIR):
-+      $(INSTALL) -d -m 755 $@
-+
-+depend:
-+      $(CPP) -M $(CFLAGS) $(PLUGINSRCS) >.depend
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/libpppoe.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/libpppoe.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/libpppoe.c       Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/libpppoe.c     Fri Mar 30 07:40:42 2001
-@@ -0,0 +1,631 @@
-+/* PPPoE support library "libpppoe"
-+ *
-+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
-+ *              Jamal Hadi Salim <hadi@cyberus.ca>
-+ *
-+ *  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 "pppoe.h"
-+
-+int disc_sock=-1;
-+
-+int verify_packet( struct session *ses, struct pppoe_packet *p);
-+
-+#define TAG_DATA(type,tag_ptr) ((type *) ((struct pppoe_tag*)tag_ptr)->tag_data)
-+
-+
-+/***************************************************************************
-+ *
-+ * Return the location where the next tag can be pu
-+ *
-+ **************************************************************************/
-+static  struct pppoe_tag *next_tag(struct pppoe_hdr *ph)
-+{
-+    return (struct pppoe_tag *)
-+      (((char *) &ph->tag) + ntohs(ph->length));
-+}
-+
-+/**************************************************************************
-+ *
-+ * Update header to reflect the addition of a new tag
-+ *
-+ **************************************************************************/
-+static  void add_tag(struct pppoe_hdr *ph, struct pppoe_tag *pt)
-+{
-+    int len = (ntohs(ph->length) +
-+             ntohs(pt->tag_len) +
-+             sizeof(struct pppoe_tag));
-+
-+    if (pt != next_tag(ph))
-+      printf("PPPoE add_tag caller is buggy\n");
-+
-+    ph->length = htons(len);
-+}
-+
-+/*************************************************************************
-+ *
-+ * Look for a tag of a specific type
-+ *
-+ ************************************************************************/
-+struct pppoe_tag *get_tag(struct pppoe_hdr *ph, u_int16_t idx)
-+{
-+    char *end = (char *) next_tag(ph);
-+    char *ptn = NULL;
-+    struct pppoe_tag *pt = &ph->tag[0];
-+
-+    /*
-+     * Keep processing tags while a tag header will still fit.
-+     *
-+     * This check will ensure that the entire tag header pointed
-+     * to by pt will fit inside the message, and thus it will be
-+     * valid to check the tag_type and tag_len fields.
-+     */
-+    while ((char *)(pt + 1) <= end) {
-+      /*
-+       * If the tag data would go past the end of the packet, abort.
-+       */
-+      ptn = (((char *) (pt + 1)) + ntohs(pt->tag_len));
-+      if (ptn > end)
-+          return NULL;
-+
-+      if (pt->tag_type == idx)
-+          return pt;
-+
-+      pt = (struct pppoe_tag *) ptn;
-+    }
-+
-+    return NULL;
-+}
-+
-+/* We want to use tag names to reference into arrays  containing the tag data.
-+   This takes an RFC 2516 tag identifier and maps it into a local one.
-+   The reverse mapping is accomplished via the tag_map array */
-+#define UNMAP_TAG(x) case PTT_##x : return TAG_##x
-+static inline int tag_index(int tag){
-+    switch(tag){
-+      UNMAP_TAG(SRV_NAME);
-+      UNMAP_TAG(AC_NAME);
-+      UNMAP_TAG(HOST_UNIQ);
-+      UNMAP_TAG(AC_COOKIE);
-+      UNMAP_TAG(VENDOR);
-+      UNMAP_TAG(RELAY_SID);
-+      UNMAP_TAG(SRV_ERR);
-+      UNMAP_TAG(SYS_ERR);
-+      UNMAP_TAG(GEN_ERR);
-+      UNMAP_TAG(EOL);
-+    };
-+    return -1;
-+}
-+
-+/*************************************************************************
-+ *
-+ * Makes a copy of a tag into a PPPoE packe
-+ *
-+ ************************************************************************/
-+void copy_tag(struct pppoe_packet *dest, struct pppoe_tag *pt)
-+{
-+    struct pppoe_tag *end_tag = get_tag(dest->hdr, PTT_EOL);
-+    int tagid;
-+    int tag_len;
-+    if( !pt ) {
-+      return;
-+    }
-+    tagid = tag_index(pt->tag_type);
-+
-+    tag_len = sizeof(struct pppoe_tag) + ntohs(pt->tag_len);
-+
-+    if( end_tag ){
-+      memcpy(((char*)end_tag)+tag_len ,
-+             end_tag, sizeof(struct pppoe_tag));
-+
-+      dest->tags[tagid]=end_tag;
-+      dest->tags[TAG_EOL] = (struct pppoe_tag*)((char*)dest->tags[TAG_EOL] + tag_len);
-+      memcpy(end_tag, pt, tag_len);
-+      dest->hdr->length = htons(ntohs(dest->hdr->length) + tag_len);
-+
-+    }else{
-+      memcpy(next_tag(dest->hdr),pt, tag_len);
-+      dest->tags[tagid]=next_tag(dest->hdr);
-+      add_tag(dest->hdr,next_tag(dest->hdr));
-+    }
-+
-+
-+}
-+
-+
-+/*************************************************************************
-+ *
-+ * Put tags from a packet into a nice array
-+ *
-+ ************************************************************************/
-+static void extract_tags(struct pppoe_hdr *ph, struct pppoe_tag** buf){
-+    int i=0;
-+    for(;i<MAX_TAGS;++i){
-+      buf[i] = get_tag(ph,tag_map[i]);
-+    }
-+}
-+
-+
-+/*************************************************************************
-+ *
-+ * Verify that a packet has a tag containint a specific value
-+ *
-+ ************************************************************************/
-+static int verify_tag(struct session* ses,
-+                    struct pppoe_packet* p,
-+                    unsigned short id,
-+                    char* data,
-+                    int data_len)
-+{
-+    int len;
-+    struct pppoe_tag *pt = p->tags[id];
-+
-+    if( !pt ){
-+      poe_info(ses,"Missing tag %d. Expected %s\n",
-+               id,data);
-+      return 0;
-+    }
-+    len = ntohs(pt->tag_len);
-+    if(len != data_len){
-+      poe_info(ses,"Length mismatch on tag %d: expect: %d got: %d\n",
-+               id, data_len, len);
-+      return 0;
-+    }
-+
-+    if( 0!=memcmp(pt->tag_data,data,data_len)){
-+      poe_info(ses,"Tag data mismatch on tag %d: expect: %s vs %s\n",
-+               id, data,pt->tag_data);
-+      return 0;
-+    }
-+    return 1;
-+}
-+
-+
-+/*************************************************************************
-+ *
-+ * Verify the existence of an ethernet device.
-+ * Construct an AF_PACKET address struct to match.
-+ *
-+ ************************************************************************/
-+int get_sockaddr_ll(const char *devnam,struct sockaddr_ll* sll){
-+    struct ifreq ifr;
-+    int retval;
-+
-+    if(disc_sock<0){
-+
-+      disc_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
-+      if( disc_sock < 0 ){
-+          return -1;
-+      }
-+    }
-+
-+    strncpy(ifr.ifr_name, devnam, sizeof(ifr.ifr_name));
-+
-+    retval = ioctl( disc_sock , SIOCGIFINDEX, &ifr);
-+
-+    if( retval < 0 ){
-+//    error("Bad device name: %s  (%m)",devnam);
-+      return 0;
-+    }
-+
-+    if(sll) sll->sll_ifindex = ifr.ifr_ifindex;
-+
-+    retval = ioctl (disc_sock, SIOCGIFHWADDR, &ifr);
-+    if( retval < 0 ){
-+//    error("Bad device name: %s  (%m)",devnam);
-+      return 0;
-+    }
-+
-+    if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
-+      error("Interface %s is not Ethernet!", devnam);
-+      return 0;
-+    }
-+    if(sll){
-+      sll->sll_family = AF_PACKET;
-+      sll->sll_protocol= ntohs(ETH_P_PPP_DISC);
-+      sll->sll_hatype = ARPHRD_ETHER;
-+      sll->sll_pkttype = PACKET_BROADCAST;
-+      sll->sll_hatype = ETH_ALEN;
-+      memcpy( sll->sll_addr , ifr.ifr_hwaddr.sa_data, ETH_ALEN);
-+    }
-+    return 1;
-+}
-+
-+
-+
-+
-+/*************************************************************************
-+ *
-+ * Construct and send a discovery message.
-+ *
-+ ************************************************************************/
-+int send_disc(struct session *ses, struct pppoe_packet *p)
-+{
-+    char buf[MAX_PAYLOAD + sizeof(struct pppoe_hdr)];
-+    int data_len = sizeof(struct pppoe_hdr);
-+
-+    struct pppoe_hdr *ph = NULL;
-+    struct pppoe_tag *tag = NULL;
-+    int i, error = 0;
-+    int got_host_uniq = 0;
-+    int got_srv_name = 0;
-+    int got_ac_name = 0;
-+
-+    for (i = 0; i < MAX_TAGS; i++) {
-+      if (!p->tags[i])
-+          continue;
-+
-+      got_host_uniq |= (p->tags[i]->tag_type == PTT_HOST_UNIQ);
-+
-+      /* Relay identifiers qualify as HOST_UNIQ's:
-+         we need HOST_UNIQ to uniquely identify the packet,
-+         PTT_RELAY_SID is sufficient for us for outgoing packets */
-+      got_host_uniq |= (p->tags[i]->tag_type == PTT_RELAY_SID);
-+
-+      got_srv_name |= (p->tags[i]->tag_type == PTT_SRV_NAME);
-+      got_ac_name  |= (p->tags[i]->tag_type == PTT_AC_NAME);
-+
-+      data_len += (ntohs(p->tags[i]->tag_len) +
-+                   sizeof(struct pppoe_tag));
-+    }
-+
-+    ph = (struct pppoe_hdr *) buf;
-+
-+
-+    memcpy(ph, p->hdr, sizeof(struct pppoe_hdr));
-+    ph->length = __constant_htons(0);
-+
-+    /* if no HOST_UNIQ tags --- add one with process id */
-+    if (!got_host_uniq){
-+      data_len += (sizeof(struct pppoe_tag) +
-+                   sizeof(struct session *));
-+      tag = next_tag(ph);
-+      tag->tag_type = PTT_HOST_UNIQ;
-+      tag->tag_len = htons(sizeof(struct session *));
-+      memcpy(tag->tag_data,
-+             &ses,
-+             sizeof(struct session *));
-+
-+      add_tag(ph, tag);
-+    }
-+
-+    if( !got_srv_name ){
-+      data_len += sizeof(struct pppoe_tag);
-+      tag = next_tag(ph);
-+      tag->tag_type = PTT_SRV_NAME;
-+      tag->tag_len = 0;
-+      add_tag(ph, tag);
-+    }
-+
-+    if(!got_ac_name && ph->code==PADO_CODE){
-+      data_len += sizeof(struct pppoe_tag);
-+      tag = next_tag(ph);
-+      tag->tag_type = PTT_AC_NAME;
-+      tag->tag_len = 0;
-+      add_tag(ph, tag);
-+    }
-+
-+    for (i = 0; i < MAX_TAGS; i++) {
-+      if (!p->tags[i])
-+          continue;
-+
-+      tag = next_tag(ph);
-+      memcpy(tag, p->tags[i],
-+             sizeof(struct pppoe_tag) + ntohs(p->tags[i]->tag_len));
-+
-+      add_tag(ph, tag);
-+    }
-+
-+    /* Now fixup the packet struct to make sure all of its pointers
-+       are self-contained */
-+    memcpy( p->hdr , ph, data_len );
-+    extract_tags( p->hdr, p->tags);
-+
-+    error = sendto(disc_sock, buf, data_len, 0,
-+                 (struct sockaddr*) &p->addr,
-+                 sizeof(struct sockaddr_ll));
-+
-+    if(error < 0)
-+      poe_error(ses,"sendto returned: %m\n");
-+
-+    return error;
-+}
-+
-+/*************************************************************************
-+ *
-+ * Verify that a packet is legal
-+ *
-+ *************************************************************************/
-+int verify_packet( struct session *ses, struct pppoe_packet *p){
-+    struct session * hu_val;
-+
-+    /* This code here should do all of the error checking and
-+       validation on the incoming packet */
-+
-+
-+    /* If we receive any error tags, abort */
-+#define CHECK_TAG(name, val)                                  \
-+    if((NULL==p->tags[name])== val){                          \
-+      poe_error(ses,"Tag error: " #name );                    \
-+      return -1;                                              \
-+    }
-+
-+
-+
-+    CHECK_TAG(TAG_SRV_ERR,0);
-+    CHECK_TAG(TAG_SYS_ERR,0);
-+    CHECK_TAG(TAG_GEN_ERR,0);
-+
-+    /* A HOST_UNIQ must be present */
-+    CHECK_TAG(TAG_HOST_UNIQ,1);
-+
-+    hu_val = *TAG_DATA(struct session* ,p->tags[TAG_HOST_UNIQ]);
-+
-+    if( hu_val != ses ){
-+      poe_info(ses,"HOST_UNIQ mismatch: %08x %i\n",(int)hu_val,getpid());
-+      return -1;
-+    }
-+
-+    if(ses->filt->htag &&
-+       !verify_tag(ses,p,TAG_HOST_UNIQ,ses->filt->htag->tag_data,(int)ntohs(ses->filt->htag->tag_len)))
-+      return -1;
-+    else
-+      poe_info(ses,"HOST_UNIQ successful match\n");
-+
-+
-+    if(ses->filt->ntag &&
-+       !verify_tag(ses,p,TAG_AC_NAME,ses->filt->ntag->tag_data,(int)ntohs(ses->filt->ntag->tag_len))){
-+      poe_info(ses,"AC_NAME failure");
-+      return -1;
-+    }
-+
-+    if(ses->filt->stag &&
-+       !verify_tag(ses,p,TAG_SRV_NAME,ses->filt->stag->tag_data,(int)ntohs(ses->filt->stag->tag_len))){
-+      poe_info(ses,"SRV_NAME failure");
-+      return -1;
-+    }
-+
-+}
-+
-+
-+/*************************************************************************
-+ *
-+ * Receive and verify an incoming packet.
-+ *
-+ *************************************************************************/
-+static int recv_disc( struct session *ses,
-+                    struct pppoe_packet *p){
-+    int error = 0;
-+    unsigned int from_len = sizeof(struct sockaddr_ll);
-+    struct session* hu_val;
-+    struct pppoe_tag *pt;
-+
-+    p->hdr = (struct pppoe_hdr*)p->buf;
-+
-+    error = recvfrom( disc_sock, p->buf, 1500, 0,
-+                    (struct sockaddr*)&p->addr, &from_len);
-+
-+    if(error < 0) return error;
-+
-+    extract_tags(p->hdr,p->tags);
-+
-+    return 1;
-+}
-+
-+
-+/*************************************************************************
-+ *
-+ * Send a PADT
-+ *
-+ *************************************************************************/
-+int session_disconnect(struct session *ses){
-+    struct pppoe_packet padt;
-+
-+    memset(&padt,0,sizeof(struct pppoe_packet));
-+    memcpy(&padt.addr, &ses->remote, sizeof(struct sockaddr_ll));
-+
-+    padt.hdr = (struct pppoe_hdr*) ses->curr_pkt.buf;
-+    padt.hdr->ver  = 1;
-+    padt.hdr->type = 1;
-+    padt.hdr->code = PADT_CODE;
-+    padt.hdr->sid  = ses->sp.sa_addr.pppoe.sid;
-+
-+    send_disc(ses,&padt);
-+    ses->sp.sa_addr.pppoe.sid = 0 ;
-+    ses->state = PADO_CODE;
-+    return 0;
-+
-+}
-+
-+
-+/*************************************************************************
-+ *
-+ * Make a connection -- behaviour depends on callbacks specified in "ses"
-+ *
-+ *************************************************************************/
-+int session_connect(struct session *ses)
-+{
-+
-+    int pkt_size=0;
-+    int ret_pkt_size=0;
-+    struct pppoe_tag *tags = NULL;
-+    struct pppoe_packet *p_out=NULL;
-+    struct pppoe_packet rcv_packet;
-+    int ret;
-+
-+
-+    if(ses->init_disc){
-+      ret = (*ses->init_disc)(ses, NULL, &p_out);
-+      if( ret != 0 ) return ret;
-+    }
-+
-+    /* main discovery loop */
-+
-+
-+    while(ses->retransmits < ses->retries || ses->retries==-1 ){
-+
-+      fd_set in;
-+      struct timeval tv;
-+      FD_ZERO(&in);
-+
-+      FD_SET(disc_sock,&in);
-+
-+      if(ses->retransmits>=0){
-+          ++ses->retransmits;
-+          tv.tv_sec = 1 << ses->retransmits;
-+          tv.tv_usec = 0;
-+          ret = select(disc_sock+1, &in, NULL, NULL, &tv);
-+      }else{
-+          ret = select(disc_sock+1, &in, NULL, NULL, NULL);
-+      }
-+
-+      if( ret == 0 ){
-+          if( DEB_DISC ){
-+              poe_dbglog(ses, "Re-sending ...");
-+          }
-+
-+          if( ses->timeout ){
-+              ret = (*ses->timeout)(ses, NULL, &p_out);
-+              if( ret != 0 )
-+                  return ret;
-+
-+          }else if(p_out){
-+              send_disc(ses,p_out);
-+          }
-+          continue;
-+      }
-+
-+
-+      ret = recv_disc(ses, &rcv_packet);
-+
-+      /* Should differentiate between system errors and
-+         bad packets and the like... */
-+      if( ret < 0 && errno != EINTR){
-+
-+          return -1;
-+      }
-+
-+
-+
-+
-+      switch (rcv_packet.hdr->code) {
-+
-+      case PADI_CODE:
-+      {
-+          if(ses->rcv_padi){
-+              ret = (*ses->rcv_padi)(ses,&rcv_packet,&p_out);
-+
-+              if( ret != 0){
-+                  return ret;
-+              }
-+          }
-+          break;
-+      }
-+
-+      case PADO_CODE:         /* wait for PADO */
-+      {
-+          if(ses->rcv_pado){
-+              ret = (*ses->rcv_pado)(ses,&rcv_packet,&p_out);
-+
-+              if( ret != 0){
-+                  return ret;
-+              }
-+          }
-+          break;
-+      }
-+
-+      case PADR_CODE:
-+      {
-+          if(ses->rcv_padr){
-+              ret = (*ses->rcv_padr)(ses,&rcv_packet,&p_out);
-+
-+              if( ret != 0){
-+                  return ret;
-+              }
-+          }
-+          break;
-+      }
-+
-+      case PADS_CODE:
-+      {
-+          if(ses->rcv_pads){
-+              ret = (*ses->rcv_pads)(ses,&rcv_packet,&p_out);
-+
-+              if( ret != 0){
-+                  return ret;
-+              }
-+          }
-+          break;
-+      }
-+
-+      case PADT_CODE:
-+      {
-+          if( rcv_packet.hdr->sid != ses->sp.sa_addr.pppoe.sid ){
-+              --ses->retransmits;
-+              continue;
-+          }
-+          if(ses->rcv_padt){
-+              ret = (*ses->rcv_padt)(ses,&rcv_packet,&p_out);
-+
-+              if( ret != 0){
-+                  return ret;
-+              }
-+          }else{
-+              poe_error (ses,"connection terminated");
-+              return (-1);
-+          }
-+          break;
-+      }
-+      default:
-+          poe_error(ses,"invalid packet %P",&rcv_packet);
-+          return (-1);
-+      }
-+    }
-+    return (0);
-+}
-+
-+
-+/*************************************************************************
-+ *
-+ * Register an ethernet address as a client of relaying services.
-+ *
-+ *************************************************************************/
-+int add_client(char *addr)
-+{
-+    struct pppoe_con* pc = (struct pppoe_con*)malloc(sizeof(struct pppoe_con));
-+    int ret;
-+    if(!pc)
-+      return -ENOMEM;
-+
-+    memset(pc, 0 , sizeof(struct pppoe_con));
-+
-+    memcpy(pc->client,addr, ETH_ALEN);
-+    memcpy(pc->key, addr, ETH_ALEN);
-+
-+    pc->key_len = ETH_ALEN;
-+
-+    if( (ret=store_con(pc)) < 0 ){
-+      free(pc);
-+    }
-+    return ret;
-+
-+}
-+
-+struct pppoe_tag *make_filter_tag(short type, short length, char* data){
-+    struct pppoe_tag *pt =
-+      (struct pppoe_tag* )malloc( sizeof(struct pppoe_tag) + length );
-+
-+    if(pt == NULL) return NULL;
-+
-+    pt->tag_len=htons(length);
-+    pt->tag_type=type;
-+
-+    if(length>0 && data){
-+      memcpy( pt+1, data, length);
-+    }
-+    return pt;
-+}
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppd_utils.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppd_utils.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/pppd_utils.c     Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppd_utils.c   Sun Aug  6 11:39:28 2000
-@@ -0,0 +1,162 @@
-+/* PPPoE support library "libpppoe"
-+ *
-+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
-+ *              Jamal Hadi Salim <hadi@cyberus.ca>
-+ *
-+ *  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 "pppoe.h"
-+
-+/*
-+ *
-+ */
-+int build_ppp_opts(char *args[],struct session *ses)
-+{
-+    char buf[256];
-+    int retval=0,i=0;
-+    
-+    memset(buf,0,256);
-+    
-+/* pppds path */
-+    if ( NULL != ses->filt->pppd){
-+      args[0]=(char *)malloc(strlen(ses->filt->pppd));
-+        strcpy (args[0],ses->filt->pppd);
-+    } else {
-+      args[0]=(char *)malloc(strlen(_PATH_PPPD));
-+        strcpy (args[0],_PATH_PPPD);
-+    }
-+    
-+/*  long device name */
-+    snprintf(buf, 256,"%02x:%02x:%02x:%02x:%02x:%02x/%04x/%s",
-+           ses->remote.sll_addr[0],
-+           ses->remote.sll_addr[1],
-+           ses->remote.sll_addr[2],
-+           ses->remote.sll_addr[3],
-+           ses->remote.sll_addr[4],
-+           ses->remote.sll_addr[5],
-+           ses->sp.sa_addr.pppoe.sid,
-+           ses->name);
-+    args[1]=(char *)malloc(strlen(buf));
-+    strcpy(args[1],buf);
-+    
-+    i=2;
-+    
-+/* override options file */
-+    if (NULL != ses->filt->fname ) {
-+      
-+      if (!ses->filt->peermode) {
-+          args[i]=(char *)malloc(strlen("file"));
-+          strcpy (args[i],"file");
-+          i++;
-+          args[i]=(char *)malloc(strlen(ses->filt->fname)+1);
-+          strcpy (args[i],ses->filt->fname);
-+          i++;
-+      } else{ /* peermode */
-+          args[i]=(char *)malloc(strlen("call"));
-+          strcpy (args[i],"call");
-+          i++;
-+          args[i]=(char *)malloc(strlen(ses->filt->fname)+1);
-+          strcpy (args[i],ses->filt->fname);
-+          i++;
-+      }
-+    }
-+    
-+/* user requested for a specific name */
-+    if (NULL != ses->filt->ntag) {
-+      if ( NULL != ses->filt->ntag->tag_data) {
-+          args[i]=(char *)malloc(strlen("pppoe_ac_name"));
-+          strcpy(args[i],"pppoe_ac_name");
-+          i++;
-+          args[i]=(char *)malloc(ntohs(ses->filt->ntag->tag_len));
-+          strcpy(args[i],ses->filt->ntag->tag_data);
-+          i++;
-+      }
-+    }
-+/* user requested for a specific service name */
-+    if (NULL != ses->filt->stag) {
-+      if ( NULL != ses->filt->stag->tag_data) {
-+          args[i]=(char *)malloc(strlen("pppoe_srv_name"));
-+          strcpy(args[i],"pppoe_srv_name");
-+          i++;
-+          args[i]=(char *)malloc(ntohs(ses->filt->stag->tag_len));
-+          strcpy(args[i],ses->filt->stag->tag_data);
-+          i++;
-+      }
-+    }
-+    
-+/*
-+ */
-+    if (ses->opt_daemonize) {
-+      args[i]=(char *)malloc(strlen("nodetach"));
-+      strcpy(args[i],"nodetach");
-+      i++;
-+    }
-+    
-+    args[i]=NULL;
-+    {
-+      int j;
-+      poe_info(ses,"calling pppd with %d args\n",i);
-+      j=i;
-+      for (i=0; i<j,NULL !=args[i]; i++) {
-+          poe_info(ses," <%d: %s > \n",i,args[i]);
-+      }
-+    }
-+    return retval;
-+}
-+
-+
-+/*
-+ *
-+ */
-+int ppp_connect (struct session *ses)
-+{
-+    int ret,pid;
-+    char *args[32];
-+    
-+    
-+    poe_info(ses,"calling ses_connect\n");
-+    do{
-+      ret = session_connect(ses);
-+    }while(ret == 0);
-+
-+    if (ret > 0 )
-+      if (ses->np == 1 && ret == 1)
-+          return ses->np; /* -G */
-+    if (ses->np == 2)
-+      return ses->np; /* -H */
-+
-+    if( ret <= 0){
-+      return ret;
-+    }
-+    
-+    poe_info(ses,"DONE calling ses_connect np is %d \n",ses->np);
-+    
-+    
-+    pid = fork ();
-+    if (pid < 0) {
-+      poe_error (ses,"unable to fork() for pppd: %m");
-+      poe_die (-1);
-+    }
-+    
-+    
-+    if(!pid) {
-+      poe_info(ses,"calling build_ppp_opts\n");
-+      if (0> build_ppp_opts(args,ses)) {
-+          poe_error(ses,"ppp_connect: failed to build ppp_opts\n");
-+          return -1;
-+      }
-+      execvp(args[0],args);
-+      poe_info (ses," child got killed");
-+    } else if( ses->type == SESSION_CLIENT) {
-+      if (!ses->opt_daemonize)
-+          return 1;
-+      pause();
-+      poe_info (ses," OK we got killed");
-+      return -1;
-+    }
-+    return 1;
-+}
-+
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.c  Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.c        Sat May 26 23:35:01 2001
-@@ -0,0 +1,385 @@
-+/* pppoe.c - pppd plugin to implement PPPoE protocol.
-+ *
-+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
-+ *              Jamal Hadi Salim <hadi@cyberus.ca>
-+ * 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 <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 "pppoe.h"
-+#if _linux_
-+extern int new_style_driver;    /* From sys-linux.c */
-+#include <linux/ppp_defs.h>
-+#include <linux/if_pppox.h>
-+#include <linux/if_ppp.h>
-+#else
-+#error this module meant for use with linux only at this time
-+#endif
-+
-+
-+#include "pppd.h"
-+#include "fsm.h"
-+#include "lcp.h"
-+#include "ipcp.h"
-+#include "ccp.h"
-+#include "pathnames.h"
-+
-+const char pppd_version[] = VERSION;
-+
-+#define _PATH_ETHOPT         _ROOT_PATH "/etc/ppp/options."
-+
-+#define PPPOE_MTU     1492
-+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
-+};
-+
-+bool  pppoe_server=0;
-+char  *pppoe_srv_name=NULL;
-+char  *pppoe_ac_name=NULL;
-+char    *hostuniq = NULL;
-+int     retries = 0;
-+
-+int setdevname_pppoe(const char *cp);
-+
-+static option_t pppoe_options[] = {
-+      { "device name", o_wild, (void *) &setdevname_pppoe,
-+        "Serial port device name",
-+        OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG  | OPT_A2STRVAL | OPT_STATIC,
-+        devnam},
-+      { "pppoe_srv_name", o_string, &pppoe_srv_name,
-+        "PPPoE service name"},
-+      { "pppoe_ac_name", o_string, &pppoe_ac_name,
-+        "PPPoE access concentrator name"},
-+      { "pppoe_hostuniq", o_string, &hostuniq,
-+        "PPPoE client uniq hostid "},
-+      { "pppoe_retransmit", o_int, &retries,
-+        "PPPoE client number of retransmit tries"},
-+      { "pppoe_server", o_bool, &pppoe_server,
-+        "PPPoE listen for incoming requests",1},
-+      { NULL }
-+};
-+
-+
-+
-+struct session *ses = NULL;
-+static int connect_pppoe_ses(void)
-+{
-+    int i,err=-1;
-+    if( pppoe_server == 1 ){
-+      srv_init_ses(ses,devnam);
-+    }else{
-+      client_init_ses(ses,devnam);
-+    }
-+#if 0
-+    ses->np=1;  /* jamal debug the discovery portion */
-+#endif
-+    strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
-+
-+    err= session_connect ( ses );
-+
-+    if(err < 0){
-+      poe_fatal(ses,"Failed to negotiate PPPoE connection: %d %m",errno,errno);
-+    }
-+
-+
-+    poe_info(ses,"Connecting PPPoE socket: %E %04x %s %p",
-+           ses->sp.sa_addr.pppoe.remote,
-+           ses->sp.sa_addr.pppoe.sid,
-+           ses->sp.sa_addr.pppoe.dev,ses);
-+
-+    err = connect(ses->fd, (struct sockaddr*)&ses->sp,
-+                sizeof(struct sockaddr_pppox));
-+
-+
-+    if( err < 0 ){
-+      poe_fatal(ses,"Failed to connect PPPoE socket: %d %m",errno,errno);
-+      return err;
-+    }
-+#if 0
-+    if (ses->np)
-+      fatal("discovery complete\n");
-+#endif
-+    /* Once the logging is fixed, print a message here indicating
-+       connection parameters */
-+
-+    return ses->fd;
-+}
-+
-+static void disconnect_pppoe_ses(void)
-+{
-+    int ret;
-+    warn("Doing disconnect");
-+    session_disconnect(ses);
-+    ses->sp.sa_addr.pppoe.sid = 0;
-+    ret = connect(ses->fd, (struct sockaddr*)&ses->sp,
-+          sizeof(struct sockaddr_pppox));
-+
-+}
-+
-+
-+static int setspeed_pppoe(const char *cp)
-+{
-+    return 0;
-+}
-+
-+static void init_device_pppoe(void)
-+{
-+    struct filter *filt;
-+    unsigned int size=0;
-+    ses=(void *)malloc(sizeof(struct session));
-+    if(!ses){
-+      fatal("No memory for new PPPoE session");
-+    }
-+    memset(ses,0,sizeof(struct session));
-+
-+    if ((ses->filt=malloc(sizeof(struct filter))) == NULL) {
-+      poe_error (ses,"failed to malloc for Filter ");
-+      poe_die (-1);
-+    }
-+
-+    filt=ses->filt;  /* makes the code more readable */
-+    memset(filt,0,sizeof(struct filter));
-+
-+    if (pppoe_ac_name !=NULL) {
-+      if (strlen (pppoe_ac_name) > 255) {
-+          poe_error (ses," AC name too long (maximum allowed 256 chars)");
-+          poe_die(-1);
-+      }
-+      ses->filt->ntag = make_filter_tag(PTT_AC_NAME,
-+                                        strlen(pppoe_ac_name),
-+                                        pppoe_ac_name);
-+
-+      if ( ses->filt->ntag== NULL) {
-+          poe_error (ses,"failed to malloc for AC name");
-+          poe_die(-1);
-+      }
-+
-+    }
-+
-+
-+    if (pppoe_srv_name !=NULL) {
-+      if (strlen (pppoe_srv_name) > 255) {
-+          poe_error (ses," Service name too long
-+                      (maximum allowed 256 chars)");
-+          poe_die(-1);
-+      }
-+      ses->filt->stag = make_filter_tag(PTT_SRV_NAME,
-+                                        strlen(pppoe_srv_name),
-+                                        pppoe_srv_name);
-+      if ( ses->filt->stag == NULL) {
-+          poe_error (ses,"failed to malloc for service name");
-+          poe_die(-1);
-+      }
-+    }
-+
-+    if (hostuniq) {
-+      ses->filt->htag = make_filter_tag(PTT_HOST_UNIQ,
-+                                        strlen(hostuniq),
-+                                        hostuniq);
-+      if ( ses->filt->htag == NULL) {
-+          poe_error (ses,"failed to malloc for Uniq Host Id ");
-+          poe_die(-1);
-+      }
-+    }
-+
-+    if (retries) {
-+      ses->retries=retries;
-+    }
-+
-+    memcpy( ses->name, devnam, IFNAMSIZ);
-+    ses->opt_debug=1;
-+}
-+
-+static void pppoe_extra_options()
-+{
-+    int ret;
-+    char buf[256];
-+    snprintf(buf, 256, _PATH_ETHOPT "%s",devnam);
-+    if(!options_from_file(buf, 0, 0, 1))
-+      exit(EXIT_OPTION_ERROR);
-+
-+}
-+
-+
-+
-+static void send_config_pppoe(int mtu,
-+                            u_int32_t asyncmap,
-+                            int pcomp,
-+                            int accomp)
-+{
-+    int sock;
-+    struct ifreq ifr;
-+
-+    if (mtu > PPPOE_MTU)
-+      warn("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_pppoe(int mru,
-+                            u_int32_t asyncmap,
-+                            int pcomp,
-+                            int accomp)
-+{
-+    if (mru > PPPOE_MTU)
-+      error("Couldn't increase MRU to %d", mru);
-+}
-+
-+static void set_xaccm_pppoe(int unit, ext_accm accm)
-+{
-+    /* NOTHING */
-+}
-+
-+
-+
-+struct channel pppoe_channel;
-+/* Check is cp is a valid ethernet 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_pppoe(const char *cp)
-+{
-+    int ret;
-+    char dev[IFNAMSIZ+1];
-+    int addr[ETH_ALEN];
-+    int sid;
-+
-+    char **a;
-+    ret =sscanf(cp, FMTSTRING(IFNAMSIZ),addr, addr+1, addr+2,
-+              addr+3, addr+4, addr+5,&sid,dev);
-+    if( ret != 8 ){
-+
-+      ret = get_sockaddr_ll(cp,NULL);
-+        if (ret < 0)
-+          fatal("PPPoE: Cannot create PF_PACKET socket for PPPoE discovery\n");
-+      if (ret == 1)
-+          strncpy(devnam, cp, sizeof(devnam));
-+    }else{
-+      /* long form parsed */
-+      ret = get_sockaddr_ll(dev,NULL);
-+        if (ret < 0)
-+          fatal("PPPoE: Cannot create PF_PACKET socket for PPPoE discovery\n");
-+
-+      strncpy(devnam, cp, sizeof(devnam));
-+      ret = 1;
-+    }
-+
-+
-+    if( ret == 1 && the_channel != &pppoe_channel ){
-+
-+      the_channel = &pppoe_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_asyncmap = 0;
-+      lcp_wantoptions[0].neg_asyncmap = 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;
-+
-+      init_device_pppoe();
-+    }
-+    return ret;
-+}
-+
-+
-+
-+void plugin_init(void)
-+{
-+/*
-+  fatal("PPPoE plugin loading...");
-+*/
-+
-+#if _linux_
-+    if (!ppp_available() && !new_style_driver)
-+      fatal("Kernel doesn't support ppp_generic needed for PPPoE");
-+#else
-+    fatal("No PPPoE support on this OS");
-+#endif
-+    add_options(pppoe_options);
-+
-+
-+    info("PPPoE Plugin Initialized");
-+}
-+
-+struct channel pppoe_channel = {
-+    options: pppoe_options,
-+    process_extra_options: &pppoe_extra_options,
-+    check_options: NULL,
-+    connect: &connect_pppoe_ses,
-+    disconnect: &disconnect_pppoe_ses,
-+    establish_ppp: &generic_establish_ppp,
-+    disestablish_ppp: &generic_disestablish_ppp,
-+    send_config: &send_config_pppoe,
-+    recv_config: &recv_config_pppoe,
-+    close: NULL,
-+    cleanup: NULL
-+};
-+
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.h ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.h
---- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.h  Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.h        Sat Mar 31 19:20:14 2001
-@@ -0,0 +1,273 @@
-+/* PPPoE support library "libpppoe"
-+ *
-+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
-+ *              Jamal Hadi Salim <hadi@cyberus.ca>
-+ *
-+ *  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.
-+ */
-+
-+#ifndef PPPOE_H
-+#define PPPOE_H       1
-+#include <stdio.h>            /* stdio               */
-+#include <stdlib.h>           /* strtoul(), realloc() */
-+#include <unistd.h>           /* STDIN_FILENO,exec    */
-+#include <string.h>           /* memcpy()             */
-+#include <errno.h>            /* errno                */
-+#include <signal.h>
-+#include <getopt.h>
-+#include <stdarg.h>
-+#include <syslog.h>
-+#include <paths.h>
-+
-+#include <sys/types.h>                /* socket types         */
-+#include <asm/types.h>
-+#include <sys/time.h>
-+#include <sys/wait.h>
-+#include <sys/fcntl.h>
-+#include <sys/ioctl.h>                /* ioctl()              */
-+#include <sys/select.h>
-+#include <sys/socket.h>               /* socket()             */
-+#include <net/if.h>           /* ifreq struct         */
-+#include <net/if_arp.h>
-+#include <netinet/in.h>
-+
-+#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
-+#include <netpacket/packet.h>
-+//#include <net/ethernet.h>
-+#else
-+#include <asm/types.h>
-+#include <linux/if_packet.h>
-+#include <linux/if_ether.h>
-+#endif
-+
-+
-+#include <asm/byteorder.h>
-+
-+/*
-+  jamal: we really have to change this
-+  to make it compatible to the 2.2 and
-+  2.3 kernel
-+*/
-+
-+#include <linux/if_pppox.h>
-+
-+
-+#define CONNECTED 1
-+#define DISCONNECTED 0
-+
-+#ifndef _PATH_PPPD
-+#define _PATH_PPPD "/usr/sbin/pppd"
-+#endif
-+
-+#ifndef LOG_PPPOE
-+#define LOG_PPPOE LOG_DAEMON
-+#endif
-+
-+
-+#define VERSION_MAJOR 0
-+#define VERSION_MINOR 4
-+#define VERSION_DATE 991120
-+
-+/* Bigger than the biggest ethernet packet we'll ever see, in bytes */
-+#define MAX_PACKET      2000
-+
-+/* references: RFC 2516 */
-+/* ETHER_TYPE fields for PPPoE */
-+
-+#define ETH_P_PPPOE_DISC 0x8863       /* discovery stage */
-+#define ETH_P_PPPOE_SESS 0x8864
-+
-+/* ethernet broadcast address */
-+#define MAC_BCAST_ADDR "\xff\xff\xff\xff\xff\xff"
-+
-+/* Format for parsing long device-name */
-+#define _STR(x) #x
-+#define FMTSTRING(size) "%x:%x:%x:%x:%x:%x/%x/%" _STR(size) "s"
-+
-+/* maximum payload length */
-+#define MAX_PAYLOAD 1484
-+
-+
-+
-+/* PPPoE tag types */
-+#define MAX_TAGS              11
-+
-+
-+/* PPPoE packet; includes Ethernet headers and such */
-+struct pppoe_packet{
-+      struct sockaddr_ll addr;
-+      struct pppoe_tag *tags[MAX_TAGS];
-+      struct pppoe_hdr *hdr;
-+      char buf[MAX_PAYLOAD];          /* buffer in which tags are held */
-+};
-+/* Defines meaning of each "tags" element */
-+
-+#define TAG_SRV_NAME  0
-+#define TAG_AC_NAME   1
-+#define TAG_HOST_UNIQ 2
-+#define TAG_AC_COOKIE 3
-+#define TAG_VENDOR    4
-+#define TAG_RELAY_SID 5
-+#define TAG_SRV_ERR     6
-+#define TAG_SYS_ERR   7
-+#define TAG_GEN_ERR   8
-+#define TAG_EOL               9
-+
-+static int tag_map[] = { PTT_SRV_NAME,
-+                       PTT_AC_NAME,
-+                       PTT_HOST_UNIQ,
-+                       PTT_AC_COOKIE,
-+                       PTT_VENDOR,
-+                       PTT_RELAY_SID,
-+                       PTT_SRV_ERR,
-+                       PTT_SYS_ERR,
-+                       PTT_GEN_ERR,
-+                       PTT_EOL
-+};
-+
-+
-+/* Debug flags */
-+int DEB_DISC,DEB_DISC2;
-+/*
-+  #define DEB_DISC            (opt_debug & 0x0002)
-+  #define DEB_DISC2           (opt_debug & 0x0004)
-+*/
-+#define MAX_FNAME             256
-+
-+
-+struct session;
-+
-+/* return <0 --> fatal error; abor
-+   return =0 --> ok, proceed
-+   return >0 --> ok, qui
-+*/
-+typedef int (*packet_cb_t)(struct session* ses,
-+                         struct pppoe_packet *p_in,
-+                         struct pppoe_packet **p_out);
-+
-+/* various override filter tags */
-+struct filter {
-+      struct pppoe_tag *stag;  /* service name tag override */
-+      struct pppoe_tag *ntag;  /*AC name override */
-+      struct pppoe_tag *htag;  /* hostuniq override */
-+      int num_restart;
-+      int peermode;
-+      char *fname;
-+      char *pppd;
-+} __attribute__ ((packed));
-+
-+
-+struct pppoe_tag *make_filter_tag(short type, short length, char* data);
-+
-+/* Session type definitions */
-+#define SESSION_CLIENT        0
-+#define SESSION_SERVER        1
-+#define SESSION_RELAY 2
-+
-+struct session {
-+
-+      /* Administrative */
-+      int type;
-+      int opt_debug;
-+      int detached;
-+      int np;
-+      int log_to_fd;
-+      int ifindex;                    /* index of device */
-+      char name[IFNAMSIZ];            /*dev name */
-+      struct pppoe_packet curr_pkt;
-+
-+      packet_cb_t init_disc;
-+      packet_cb_t rcv_pado;
-+      packet_cb_t rcv_padi;
-+      packet_cb_t rcv_pads;
-+      packet_cb_t rcv_padr;
-+      packet_cb_t rcv_padt;
-+      packet_cb_t timeout;
-+
-+
-+      /* Generic */
-+      struct filter *filt;
-+      struct sockaddr_ll local;
-+      struct sockaddr_ll remote;
-+      struct sockaddr_pppox sp;
-+      int fd;                         /* fd of PPPoE socket */
-+
-+
-+      /* For client */
-+      int retransmits;                /* Number of retransmission performed
-+                                         if < 0 , retransmissions disabled */
-+      int retries;
-+      int state;
-+      int opt_daemonize;
-+
-+      /* For server */
-+      int fork;
-+
-+      /* For forwarding */
-+      int fwd_sock;
-+      char fwd_name[IFNAMSIZ];        /* Name of device to forward to */
-+} __attribute__ ((packed));
-+
-+/*
-+  retransmit retries for the PADR and PADI packets
-+  during discovery
-+*/
-+int PADR_ret;
-+int PADI_ret;
-+
-+int log_to_fd;
-+int ctrl_fd;
-+int opt_debug;
-+int opt_daemonize;
-+
-+
-+/* Structure for keeping track of connection relays */
-+struct pppoe_con{
-+      struct pppoe_con *next;
-+      int id;
-+      int connected;
-+      int  cl_sock;
-+      int  sv_sock;
-+      int ref_count;
-+      char client[ETH_ALEN];
-+      char server[ETH_ALEN];
-+      char key_len;
-+      char key[32];
-+};
-+
-+/* Functions exported from utils.c. */
-+
-+/* Functions exported from pppoehash.c */
-+struct pppoe_con *get_con(int len, char *key);
-+int store_con(struct pppoe_con *pc);
-+struct pppoe_con *delete_con(unsigned long len, char *key);
-+
-+/* exported by lib.c */
-+
-+extern int init_lib();
-+
-+extern int get_sockaddr_ll(const char *devnam,struct sockaddr_ll* sll);
-+
-+extern int client_init_ses (struct session *ses, char* devnam);
-+extern int relay_init_ses(struct session *ses, char* from, char* to);
-+extern int srv_init_ses(struct session *ses, char* from);
-+extern int session_connect(struct session *ses);
-+extern int session_disconnect(struct session*ses);
-+
-+extern int verify_packet( struct session *ses, struct pppoe_packet *p);
-+
-+extern void copy_tag(struct pppoe_packet *dest, struct pppoe_tag *pt);
-+extern struct pppoe_tag *get_tag(struct pppoe_hdr *ph, u_int16_t idx);
-+extern int send_disc(struct session *ses, struct pppoe_packet *p);
-+
-+
-+extern int add_client(char *addr);
-+
-+/* Make connections (including spawning pppd) as server/client */
-+extern ppp_connect(struct session *ses);
-+
-+
-+#endif
-Binary files ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.so and ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.so differ
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_client.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_client.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_client.c   Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_client.c Sun Aug  6 11:39:28 2000
-@@ -0,0 +1,232 @@
-+/* PPPoE support library "libpppoe"
-+ *
-+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
-+ *              Jamal Hadi Salim <hadi@cyberus.ca>
-+ *
-+ *  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 "pppoe.h"
-+
-+
-+
-+static int std_rcv_pado(struct session* ses,
-+                      struct pppoe_packet *p_in,
-+                      struct pppoe_packet **p_out){
-+    
-+    if( verify_packet(ses, p_in) < 0)
-+      return -1;
-+    
-+    if(ses->state != PADO_CODE ){
-+      poe_error(ses,"Unexpected packet: %P",p_in);
-+      return 0;
-+    }
-+    
-+    
-+    if (DEB_DISC2) {
-+      poe_dbglog (ses,"PADO received: %P", p_in);
-+    }
-+    
-+    memcpy(&ses->remote, &p_in->addr, sizeof(struct sockaddr_ll));
-+    memcpy( &ses->curr_pkt.addr, &ses->remote , sizeof(struct sockaddr_ll));
-+    
-+    ses->curr_pkt.hdr->code = PADR_CODE;
-+    
-+    /* The HOST_UNIQ has been verified already... there's no "if" about this */
-+    /* if(ses->filt->htag) */
-+    copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_HOST_UNIQ));        
-+    
-+    if (ses->filt->ntag) {
-+      ses->curr_pkt.tags[TAG_AC_NAME]=NULL;
-+    }
-+//    copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_AC_NAME));
-+    
-+    if(ses->filt->stag) {
-+      ses->curr_pkt.tags[TAG_SRV_NAME]=NULL;
-+    }
-+    copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_SRV_NAME));
-+    
-+    copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_AC_COOKIE));
-+    copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_RELAY_SID));
-+    
-+    ses->state = PADS_CODE;
-+    
-+    ses->retransmits = 0;
-+    
-+    send_disc(ses, &ses->curr_pkt);
-+    (*p_out) = &ses->curr_pkt;
-+    
-+    if (ses->np)
-+      return 1;
-+    
-+    return 0;
-+}
-+
-+static int std_init_disc(struct session* ses,
-+                       struct pppoe_packet *p_in,
-+                       struct pppoe_packet **p_out){
-+    
-+    memset(&ses->curr_pkt,0, sizeof(struct pppoe_packet));
-+
-+    
-+    /* Check if already connected */
-+    if( ses->state != PADO_CODE ){
-+      return 1;
-+    }
-+    
-+    ses->curr_pkt.hdr = (struct pppoe_hdr*) ses->curr_pkt.buf;
-+    ses->curr_pkt.hdr->ver  = 1;
-+    ses->curr_pkt.hdr->type = 1;
-+    ses->curr_pkt.hdr->code = PADI_CODE;
-+    
-+    
-+    memcpy( &ses->curr_pkt.addr, &ses->remote , sizeof(struct sockaddr_ll));
-+    
-+    poe_info (ses,"Sending PADI");
-+    if (DEB_DISC)
-+      poe_dbglog (ses,"Sending PADI");
-+    
-+    ses->retransmits = 0 ;
-+    
-+    if(ses->filt->ntag) {
-+      ses->curr_pkt.tags[TAG_AC_NAME]=ses->filt->ntag;
-+      poe_info(ses,"overriding AC name\n");
-+    }
-+    
-+    if(ses->filt->stag)
-+      ses->curr_pkt.tags[TAG_SRV_NAME]=ses->filt->stag;
-+    
-+    if(ses->filt->htag)
-+      ses->curr_pkt.tags[TAG_HOST_UNIQ]=ses->filt->htag;
-+    
-+    send_disc(ses, &ses->curr_pkt);
-+    (*p_out)= &ses->curr_pkt;
-+    return 0;
-+}
-+
-+
-+static int std_rcv_pads(struct session* ses,
-+                      struct pppoe_packet *p_in,
-+                      struct pppoe_packet **p_out){
-+    if( verify_packet(ses, p_in) < 0)
-+      return -1;
-+    
-+    if (DEB_DISC)
-+      poe_dbglog (ses,"Got connection: %x",
-+                  ntohs(p_in->hdr->sid));
-+    poe_info (ses,"Got connection: %x", ntohs(p_in->hdr->sid));
-+    
-+    ses->sp.sa_family = AF_PPPOX;
-+    ses->sp.sa_protocol = PX_PROTO_OE;
-+    ses->sp.sa_addr.pppoe.sid = p_in->hdr->sid;
-+    memcpy(ses->sp.sa_addr.pppoe.dev,ses->name, IFNAMSIZ);
-+    memcpy(ses->sp.sa_addr.pppoe.remote, p_in->addr.sll_addr, ETH_ALEN);
-+    
-+    
-+    return 1;
-+}
-+
-+static int std_rcv_padt(struct session* ses,
-+                      struct pppoe_packet *p_in,
-+                      struct pppoe_packet **p_out){
-+    ses->state = PADO_CODE;
-+    return 0;
-+}
-+
-+
-+extern int disc_sock;
-+int client_init_ses (struct session *ses, char* devnam)
-+{
-+    int i=0;
-+    int retval;
-+    char dev[IFNAMSIZ+1];
-+    int addr[ETH_ALEN];
-+    int sid;
-+    
-+    /* do error checks here; session name etc are valid */
-+//    poe_info (ses,"init_ses: creating socket");
-+    
-+    /* Make socket if necessary */
-+    if( disc_sock < 0 ){
-+      
-+      disc_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
-+      if( disc_sock < 0 ){
-+          poe_fatal(ses,
-+                    "Cannot create PF_PACKET socket for PPPoE discovery\n");
-+      }
-+      
-+    }
-+    
-+    /* Check for long format */
-+    retval =sscanf(devnam, FMTSTRING(IFNAMSIZ),addr, addr+1, addr+2,
-+                 addr+3, addr+4, addr+5,&sid,dev);
-+    if( retval != 8 ){
-+      /* Verify the device name , construct ses->local */
-+      retval = get_sockaddr_ll(devnam,&ses->local);
-+      if (retval < 0)
-+          poe_fatal(ses, "client_init_ses: "
-+                    "Cannot create PF_PACKET socket for PPPoE discovery\n");
-+      
-+      
-+      ses->state = PADO_CODE;
-+      memcpy(&ses->remote, &ses->local, sizeof(struct sockaddr_ll) );
-+      
-+      memset( ses->remote.sll_addr, 0xff, ETH_ALEN);
-+    }else{
-+      /* long form parsed */
-+
-+      /* Verify the device name , construct ses->local */
-+      retval = get_sockaddr_ll(dev,&ses->local);
-+      if (retval < 0)
-+          poe_fatal(ses,"client_init_ses(2): "
-+                    "Cannot create PF_PACKET socket for PPPoE discovery\n");
-+      ses->state = PADS_CODE;
-+      ses->sp.sa_family = AF_PPPOX;
-+      ses->sp.sa_protocol = PX_PROTO_OE;
-+      ses->sp.sa_addr.pppoe.sid = sid;
-+      
-+      memcpy(&ses->remote, &ses->local, sizeof(struct sockaddr_ll) );
-+      
-+      for(; i < ETH_ALEN ; ++i ){
-+          ses->sp.sa_addr.pppoe.remote[i] = addr[i];
-+          ses->remote.sll_addr[i]=addr[i];
-+      }
-+      memcpy(ses->sp.sa_addr.pppoe.dev, dev, IFNAMSIZ);
-+      
-+      
-+      
-+    }
-+    if( retval < 0 )
-+      error("bad device name: %s",devnam);
-+    
-+    
-+    retval = bind( disc_sock ,
-+                 (struct sockaddr*)&ses->local,
-+                 sizeof(struct sockaddr_ll));
-+    
-+    
-+    if( retval < 0 ){
-+      error("bind to PF_PACKET socket failed: %m");
-+    }
-+    
-+    ses->fd = socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_OE);
-+    if(ses->fd < 0)
-+    {
-+      poe_fatal(ses,"Failed to create PPPoE socket: %m");
-+    }
-+    
-+    
-+    ses->init_disc = std_init_disc;
-+    ses->rcv_pado  = std_rcv_pado;
-+    ses->rcv_pads  = std_rcv_pads;
-+    ses->rcv_padt  = std_rcv_padt;
-+    
-+    /* this should be filter overridable */
-+    ses->retries = 10;
-+    
-+    return ses->fd;
-+}
-+
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_relay.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_relay.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_relay.c    Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_relay.c  Sun Aug  6 11:39:28 2000
-@@ -0,0 +1,260 @@
-+/* PPPoE support library "libpppoe"
-+ *
-+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
-+ *              Jamal Hadi Salim <hadi@cyberus.ca>
-+ *
-+ *  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 "pppoe.h"
-+
-+static int relay_init_disc(struct session* ses,
-+                         struct pppoe_packet *p_in,
-+                         struct pppoe_packet **p_out){
-+
-+    ses->state = 0;
-+    ses->retransmits = -1 ;
-+    ses->retries = -1;
-+
-+    (*p_out) = NULL;
-+    return 0;
-+}
-+
-+static int pcid=0;
-+static int relay_rcv_padi(struct session* ses,
-+                        struct pppoe_packet *p_in,
-+                        struct pppoe_packet **p_out){
-+    char tag_buf[32];
-+    struct pppoe_con *newpc = NULL;
-+    struct pppoe_tag *tag = (struct pppoe_tag *) tag_buf;
-+
-+
-+    tag->tag_type = PTT_RELAY_SID;
-+    tag->tag_len  = htons(ETH_ALEN + sizeof(struct session *));
-+
-+    memcpy(tag->tag_data, p_in->addr.sll_addr, ETH_ALEN);
-+    memcpy(tag->tag_data + ETH_ALEN, &ses, sizeof(struct session *));
-+
-+    if(! p_in->tags[TAG_RELAY_SID] ){
-+      copy_tag(p_in, tag);
-+    }
-+
-+
-+    poe_dbglog(ses, "Recv'd PADI: %P",p_in);
-+    poe_dbglog(ses, "Recv'd packet: %P",p_in);
-+    newpc = get_con( ntohs(tag->tag_len), tag->tag_data );
-+    if(!newpc){
-+      
-+      newpc = (struct pppoe_con *) malloc(sizeof(struct pppoe_con));
-+      memset(newpc , 0, sizeof(struct pppoe_con));
-+      
-+      newpc->id = pcid++;
-+      
-+      newpc->key_len = ntohs(p_in->tags[TAG_RELAY_SID]->tag_len);
-+      memcpy(newpc->key, p_in->tags[TAG_RELAY_SID]->tag_data, newpc->key_len);
-+      memcpy(newpc->client, p_in->addr.sll_addr, ETH_ALEN);
-+      
-+      memcpy(newpc->server, MAC_BCAST_ADDR, ETH_ALEN);
-+      
-+      store_con(newpc);
-+      
-+    }
-+
-+    ++newpc->ref_count;
-+
-+    memset(p_in->addr.sll_addr, 0xff, ETH_ALEN);
-+
-+    p_in->addr.sll_ifindex = ses->remote.sll_ifindex;
-+
-+    send_disc(ses, p_in);
-+    return 0;
-+}
-+
-+static int relay_rcv_pkt(struct session* ses,
-+                       struct pppoe_packet *p_in,
-+                       struct pppoe_packet **p_out){
-+    struct pppoe_con *pc;
-+    char tag_buf[32];
-+    struct pppoe_tag *tag = p_in->tags[TAG_RELAY_SID];
-+
-+    if( !tag ) return 0;
-+
-+    pc = get_con(ntohs(tag->tag_len),tag->tag_data);
-+
-+    if( !pc ) return 0;
-+
-+    poe_dbglog(ses, "Recv'd packet: %P",p_in);
-+
-+    if( memcmp(pc->client , p_in->addr.sll_addr , ETH_ALEN ) == 0 ){
-+      
-+      memcpy(p_in->addr.sll_addr, pc->server, ETH_ALEN);
-+      p_in->addr.sll_ifindex = ses->remote.sll_ifindex;
-+      
-+    }else{
-+      if( memcmp(pc->server, MAC_BCAST_ADDR, ETH_ALEN) == 0 ){
-+          memcpy(pc->server, p_in->addr.sll_addr, ETH_ALEN);
-+      
-+      }else if( memcmp(pc->server, p_in->addr.sll_addr, ETH_ALEN) !=0){
-+          return 0;
-+      }
-+      
-+      memcpy(p_in->addr.sll_addr, pc->client, ETH_ALEN);
-+      p_in->addr.sll_ifindex = ses->local.sll_ifindex;
-+      
-+      
-+    }
-+
-+
-+    send_disc(ses, p_in);
-+    return 0;
-+}
-+
-+static int relay_rcv_pads(struct session* ses,
-+                        struct pppoe_packet *p_in,
-+                        struct pppoe_packet **p_out){
-+
-+    struct pppoe_con *pc;
-+    char tag_buf[32];
-+    struct pppoe_tag *tag = p_in->tags[TAG_RELAY_SID];
-+    struct sockaddr_pppox sp_cl= { AF_PPPOX, PX_PROTO_OE,
-+                                 { p_in->hdr->sid, {0,},{0,}}};
-+
-+    struct sockaddr_pppox sp_sv= { AF_PPPOX, PX_PROTO_OE,
-+                                 { p_in->hdr->sid, {0,},{0,}}};
-+
-+    int ret;
-+
-+
-+    if( !tag ) return 0;
-+
-+    pc = get_con(ntohs(tag->tag_len),tag->tag_data);
-+
-+    if( !pc ) return 0;
-+
-+
-+    if(!pc->connected){
-+      
-+      pc->sv_sock = socket( AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE);
-+      if( pc->sv_sock < 0){
-+          poe_fatal(ses,"Cannot open PPPoE socket: %i",errno);
-+      }
-+      
-+      pc->cl_sock = socket( AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE);
-+      if( pc->cl_sock < 0){
-+          poe_fatal(ses,"Cannot open PPPoE socket: %i",errno);
-+      }
-+      
-+      memcpy( sp_sv.sa_addr.pppoe.dev, ses->fwd_name, IFNAMSIZ);
-+      memcpy( sp_sv.sa_addr.pppoe.remote, pc->server, ETH_ALEN);
-+      
-+      ret = connect( pc->sv_sock,
-+                     (struct sockaddr*)&sp_sv,
-+                     sizeof(struct sockaddr_pppox));
-+      if( ret < 0){
-+          poe_fatal(ses,"Cannot connect PPPoE socket: %i",errno);
-+      }
-+      
-+      memcpy( sp_cl.sa_addr.pppoe.dev, ses->name, IFNAMSIZ);
-+      memcpy( sp_cl.sa_addr.pppoe.remote, pc->client, ETH_ALEN);
-+      
-+      ret = connect( pc->cl_sock,
-+                     (struct sockaddr*)&sp_cl,
-+                     sizeof(struct sockaddr_pppox));
-+      if( ret < 0){
-+          poe_fatal(ses,"Cannot connect PPPoE socket: %i",errno);
-+      }
-+      
-+      
-+      ret = ioctl( pc->sv_sock, PPPOEIOCSFWD, &sp_cl);
-+      if( ret < 0){
-+          poe_fatal(ses,"Cannot set forwarding on PPPoE socket: %i",errno);
-+      }
-+      
-+      ret = ioctl( pc->cl_sock, PPPOEIOCSFWD, &sp_sv);
-+      if( ret < 0){
-+          poe_fatal(ses,"Cannot set forwarding on PPPoE socket: %i",errno);
-+      }
-+      
-+      pc->connected = 1;
-+    }
-+
-+    poe_info(ses,"PPPoE relay for %E established to %E (sid=%04x)\n",
-+           pc->client,pc->server, p_in->hdr->sid);
-+
-+    return relay_rcv_pkt(ses,p_in,p_out);
-+}
-+
-+
-+static int relay_rcv_padt(struct session* ses,
-+                        struct pppoe_packet *p_in,
-+                        struct pppoe_packet **p_out){
-+
-+    int ret;
-+    struct pppoe_con *pc;
-+    char tag_buf[32];
-+    struct pppoe_tag *tag = p_in->tags[TAG_RELAY_SID];
-+
-+    if( !tag ) return 0;
-+
-+    pc = get_con(ntohs(tag->tag_len),tag->tag_data);
-+
-+    if( !pc ) return 0;
-+
-+    ret = relay_rcv_pkt(ses,p_in,p_out);
-+
-+
-+    if(pc->cl_sock>0){
-+      close(pc->cl_sock);
-+    }
-+
-+    if(pc->sv_sock>0){
-+      close(pc->sv_sock);
-+    }
-+
-+    --pc->ref_count;
-+    if( pc->ref_count == 0 ){
-+      delete_con(pc->key_len, pc->key);
-+      
-+      free(pc);
-+    }
-+}
-+
-+
-+int relay_init_ses(struct session *ses, char* from, char* to)
-+{
-+    int retval = client_init_ses(ses, from);
-+
-+    if(retval<0) return retval;
-+
-+    ses->fwd_sock =  socket(PF_PACKET, SOCK_DGRAM, 0);
-+    if( ses->fwd_sock < 0 ) {
-+      poe_fatal(ses,"Cannot create PF_PACKET socket for PPPoE forwarding\n");
-+    }
-+
-+    /* Verify the device name , construct ses->local */
-+    retval = get_sockaddr_ll(to, &ses->remote);
-+    if (retval < 0)
-+      poe_fatal(ses,"relay_init_ses:get_sockaddr_ll failed %m");
-+
-+    retval = bind( ses->fwd_sock ,
-+                 (struct sockaddr*)&ses->remote,
-+                 sizeof(struct sockaddr_ll));
-+
-+    if( retval < 0 ){
-+      poe_fatal(ses,"bind to PF_PACKET socket failed: %m");
-+    }
-+
-+    memcpy(ses->fwd_name, to, IFNAMSIZ);
-+    memcpy(ses->name, from, IFNAMSIZ);
-+
-+
-+    ses->init_disc = relay_init_disc;
-+    ses->rcv_padi  = relay_rcv_padi;
-+    ses->rcv_pado  = relay_rcv_pkt;
-+    ses->rcv_padr  = relay_rcv_pkt;
-+    ses->rcv_pads  = relay_rcv_pads;
-+    ses->rcv_padt  = relay_rcv_padt;
-+}
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_server.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_server.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_server.c   Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_server.c Sun Aug  6 11:39:28 2000
-@@ -0,0 +1,143 @@
-+/* PPPoE support library "libpppoe"
-+ *
-+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
-+ *              Jamal Hadi Salim <hadi@cyberus.ca>
-+ *
-+ *  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 "pppoe.h"
-+#include <unistd.h>
-+
-+static unsigned int pcid=1111;
-+static int srv_rcv_padi(struct session* ses, 
-+                      struct pppoe_packet *p_in,
-+                      struct pppoe_packet **p_out){
-+    struct pppoe_con *newpc = NULL;
-+    struct pppoe_tag *tag;
-+    
-+    poe_dbglog(ses,"Srv Recv'd packet: %P\n",p_in);
-+    
-+    
-+    ses->curr_pkt.hdr = (struct pppoe_hdr*) ses->curr_pkt.buf;
-+    ses->curr_pkt.hdr->ver  = 1;
-+    ses->curr_pkt.hdr->type = 1;
-+
-+    tag = get_tag(p_in->hdr,PTT_SRV_NAME);
-+
-+    if(!tag )
-+      return 0;
-+
-+    if( ntohs(tag->tag_len)==0 ){
-+      ses->curr_pkt.tags[TAG_SRV_NAME] = ses->filt->stag ;
-+    }else if( tag->tag_len != ses->filt->stag->tag_len
-+            || !memcmp( tag+1, ses->filt->stag, ntohs(tag->tag_len)) ){
-+      return 0;
-+    }else{
-+      ses->curr_pkt.tags[TAG_SRV_NAME] = tag;
-+    }
-+
-+    ses->curr_pkt.tags[ TAG_AC_NAME] = ses->filt->ntag ;
-+    ses->curr_pkt.tags[ TAG_HOST_UNIQ ] = get_tag(p_in->hdr,PTT_HOST_UNIQ);
-+    
-+    memcpy(&ses->remote, &p_in->addr, sizeof(struct sockaddr_ll));
-+    memcpy( &ses->curr_pkt.addr, &ses->remote , sizeof(struct sockaddr_ll));
-+    
-+    ses->curr_pkt.hdr->code =  PADO_CODE;
-+    
-+    
-+    ses->curr_pkt.tags[ TAG_RELAY_SID ] = get_tag(p_in->hdr,PTT_RELAY_SID);
-+
-+    send_disc(ses, &ses->curr_pkt);
-+    poe_dbglog(ses,"Srv Sent packet: %P\n",&ses->curr_pkt);
-+    
-+    return 0;
-+}
-+
-+
-+static int srv_rcv_padr(struct session* ses, 
-+                      struct pppoe_packet *p_in,
-+                      struct pppoe_packet **p_out){
-+    struct pppoe_tag *tag;
-+
-+    poe_dbglog(ses,"Recv'd packet: %P\n",p_in);
-+    
-+
-+
-+    /* Run checks to ensure this packets asks for 
-+       what we're willing to offer */
-+
-+    tag = get_tag(p_in->hdr,PTT_SRV_NAME);
-+
-+    if(!tag || tag->tag_len == 0 ){
-+      p_in->tags[TAG_SRV_NAME] = ses->filt->stag;
-+
-+    }else if( tag->tag_len != ses->filt->stag->tag_len
-+           || !memcmp(tag + 1 , ses->filt->stag, ntohs(tag->tag_len)) ){
-+      return 0;
-+    }else{
-+      p_in->tags[TAG_SRV_NAME] = tag;
-+    }
-+
-+    tag = get_tag(p_in->hdr,PTT_AC_NAME);
-+    if( !tag || tag->tag_len==0 ){
-+      p_in->tags[TAG_AC_NAME] = ses->filt->ntag;
-+    }else if( tag->tag_len != ses->filt->ntag->tag_len
-+        || !memcmp(tag + 1, ses->filt->ntag, ntohs(tag->tag_len)) ){
-+      return 0;
-+    }else{
-+      p_in->tags[TAG_AC_NAME] = tag;
-+    }
-+
-+    
-+    
-+    
-+    pcid = ++pcid & 0x0000ffff ;
-+    if(pcid == 0 ){
-+      pcid = 1111;
-+    }
-+    
-+    p_in->hdr->sid  = ntohs(pcid);
-+    
-+    p_in->hdr->code = PADS_CODE;
-+    send_disc(ses, p_in);
-+    
-+    poe_dbglog(ses,"Sent packet: %P\n",p_in);
-+    
-+    ses->sp.sa_family = AF_PPPOX;
-+    ses->sp.sa_protocol=PX_PROTO_OE;
-+    ses->sp.sa_addr.pppoe.sid = p_in->hdr->sid;
-+    memcpy(ses->sp.sa_addr.pppoe.dev, ses->name, IFNAMSIZ);
-+    memcpy(ses->sp.sa_addr.pppoe.remote, p_in->addr.sll_addr, ETH_ALEN);
-+    memcpy(&ses->remote, &p_in->addr, sizeof(struct sockaddr_ll));
-+    return 1;
-+}
-+
-+static int srv_rcv_padt(struct session* ses, 
-+                      struct pppoe_packet *p_in,
-+                      struct pppoe_packet **p_out){
-+    return 0;
-+}
-+
-+
-+
-+int srv_init_ses(struct session *ses, char* from)
-+{
-+    int retval;
-+    retval = client_init_ses(ses, from);
-+    ses->init_disc = NULL;
-+    ses->rcv_pado  = NULL;
-+    ses->rcv_pads  = NULL;
-+    ses->rcv_padi  = srv_rcv_padi;
-+    ses->rcv_padr  = srv_rcv_padr;
-+    ses->rcv_padt  = srv_rcv_padt;
-+
-+    /* retries forever */
-+    ses->retries   = -1;
-+
-+    return retval;
-+}
-+
-+
-Binary files ppp-2.4.1.orig/pppd/plugins/pppoe/pppoed and ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoed differ
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoed.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoed.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoed.c Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoed.c       Sun Aug  6 11:39:28 2000
-@@ -0,0 +1,283 @@
-+/* PPPoE support library "libpppoe"
-+ *
-+ * Copyright 2000 Jamal Hadi Salim <hadi@cyberus.ca>
-+ *
-+ *  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 "pppoe.h"
-+
-+int detached=1;
-+void
-+sigproc (int src)
-+{
-+    int i;
-+    fprintf (stderr,"Received signal %d", src);
-+}
-+
-+void
-+sigchild (int src)
-+{
-+    pid_t pid;
-+    int status;
-+    int i;
-+    pid = waitpid (-1, &status, WNOHANG);
-+    
-+    if (!detached)
-+      fprintf (stderr,"Child received signal %d PID %d, status %d", src, pid, status);
-+    if (pid < 1) {
-+      return;
-+    }
-+}
-+
-+void
-+print_help ()
-+{
-+    
-+    fprintf (stdout,"\npppoe version %d.%d build %d", VERSION_MAJOR, VERSION_MINOR,
-+           VERSION_DATE);
-+    fprintf (stdout,"\nrecognized options are:");
-+    fprintf (stdout,"\n -I <interface> : overrides the default interface of eth0");
-+    fprintf (stdout,"\n -S : starts pppoed in server mode");
-+    fprintf (stdout,"\n -R <num_retries>: forces pppoed to be restarted num_retries");
-+    fprintf (stdout,"\n                   should the other end be detected to be dead.");
-+    fprintf (stdout,"\n                   Needs lcp_echo. Read the INSTALL file instructions");
-+    fprintf (stdout,"\n -F <filename> : specifies additional ppp options file");
-+    fprintf (stdout,"\n -C <filename> : ppp options file in /etc/ppp/peers/");
-+    fprintf (stdout,"\n -d <level> : sets debug level");
-+    fprintf (stdout,"\n -D : prevents pppoed from detaching itself and running in the background");
-+    fprintf (stdout,"\n -P <path to pppd> : selects a different pppd. Defaults to " _PATH_PPPD);
-+    fprintf (stdout,"\n -A <AC name> to select a specific AC by name");
-+    fprintf (stdout,"\n -E <AC service name> to select a specific AC service by name");
-+    fprintf (stdout,"\n -G Do service discovery only");
-+    fprintf (stdout,"\n -H Do service discovery and connection (no pppd)\n");
-+}
-+
-+
-+int 
-+get_args (int argc, char **argv,struct session *sess)
-+{
-+    struct filter *filt;
-+    struct host_tag *tg;
-+    int opt;
-+    
-+
-+    sess->opt_debug = 0;
-+    DEB_DISC=0;
-+    DEB_DISC2=0;
-+    sess->log_to_fd = 1;
-+    sess->np = 0;
-+    sess->opt_daemonize = 0;
-+    
-+    sess->log_to_fd = fileno (stdout);
-+    
-+/* defaults to eth0 */
-+    strcpy (sess->name, "eth0");
-+    
-+    
-+    if ((sess->filt=malloc(sizeof(struct filter))) == NULL) {
-+        poe_error (sess,"failed to malloc for Filter ");
-+        poe_die (-1);
-+    }
-+    
-+    filt=sess->filt;  /* makes the code more readable */
-+    memset(filt,0,sizeof(struct filter));
-+    
-+    filt->num_restart=1;
-+    
-+/* set default filters; move this to routine */
-+    /* parse options */
-+    
-+    while ((opt = getopt (argc, argv, "A:C:E:d:DR:I:F:L:V:P:SN:GH")) != -1)
-+      
-+      switch (opt) {
-+      case 'R':                       /* sets number of retries */
-+          filt->num_restart = strtol (optarg, (char **) NULL, 10);
-+          filt->num_restart += 1;
-+          break;
-+      case 'I':                       /* sets interface */
-+          if (strlen (optarg) >= IFNAMSIZ) {
-+              poe_error (sess,"interface name cannot exceed %d characters", IFNAMSIZ - 1);
-+              return (-1);
-+          }
-+          strncpy (sess->name, optarg, strlen(optarg)+1);
-+          break;
-+      case 'C':                       /* name of the file in /etc/ppp/peers */
-+          if (NULL != filt->fname) {
-+              poe_error (sess,"-F can not be used with -C");
-+              return (-1);
-+          }
-+          if (strlen(optarg) > MAX_FNAME) {
-+              poe_error (sess,"file name cannot exceed %d characters", MAX_FNAME - 1);
-+              return (-1);
-+          }
-+          filt->fname=malloc(strlen(optarg));
-+          strncpy (filt->fname, optarg, strlen(optarg));
-+          filt->peermode=1;
-+          break;
-+      case 'F':                       /* sets the options file */
-+          if (NULL != filt->fname) {
-+              poe_error (sess,"-F can not be used with -C");
-+              return (-1);
-+          }
-+          
-+          if (strlen(optarg) > MAX_FNAME) {
-+              poe_error (sess,"file name cannot exceed %d characters", MAX_FNAME - 1);
-+              return (-1);
-+          }
-+          filt->fname=malloc(strlen(optarg)+1);
-+          strncpy (filt->fname, optarg, strlen(optarg)+1);
-+          
-+          poe_info (sess,"selected %s as filename\n",filt->fname);
-+          break;
-+      case 'D':                       /* don't daemonize */
-+          sess->opt_daemonize = 1;
-+          detached=0;
-+          break;
-+      case 'd':                       /* debug level */
-+          sess->opt_debug = strtol (optarg, (char **) NULL, 10);
-+          if (sess->opt_debug & 0x0002)
-+              DEB_DISC=1;
-+          if (sess->opt_debug & 0x0004)
-+              DEB_DISC2=1;
-+          break;
-+      case 'P':                       /* sets the pppd binary */
-+          if (strlen(optarg) > MAX_FNAME) {
-+              poe_error (sess,"pppd binary cant exceed %d characters", MAX_FNAME - 1);
-+              return (-1);
-+          }
-+          filt->pppd=malloc(strlen(optarg));
-+          strncpy (filt->pppd, optarg, strlen(optarg));
-+          break;
-+      case 'H':                       
-+          sess->np = 2;
-+          break;
-+      case 'G':                       
-+          sess->np = 1;
-+          break;
-+      case 'V':                       /* version */
-+          fprintf (stdout,"pppoe version %d.%d build %d", VERSION_MAJOR,
-+                   VERSION_MINOR, VERSION_DATE);
-+          return (0);
-+      case 'S':                       /* server mode */
-+          sess->type = SESSION_SERVER;
-+          break;
-+      case 'A':                       /* AC override */
-+          poe_info (sess,"AC name override to %s", optarg);
-+          if (strlen (optarg) > 255) {
-+              poe_error (sess," AC name too long 
-+                        (maximum allowed 256 chars)");
-+              poe_die(-1);
-+          }
-+          if ((sess->filt->ntag= malloc (sizeof (struct pppoe_tag) + 
-+                                         strlen (optarg)))== NULL) {
-+              poe_error (sess,"failed to malloc for AC name");
-+              poe_die(-1);
-+          }
-+          sess->filt->ntag->tag_len=htons(strlen(optarg));
-+          sess->filt->ntag->tag_type=PTT_AC_NAME;
-+          poe_error (sess," pppoe_ac_name: AC name Override %p\n",
-+                     sess->filt->ntag);
-+          strcpy(sess->filt->ntag->tag_data,optarg);
-+          break;
-+      case 'E':                       /* AC service name override */
-+          poe_info (sess,"AC service name override to %s", optarg);
-+          if (strlen (optarg) > 255) {
-+              poe_error (sess," Service name too long 
-+                (maximum allowed 256 chars)");
-+              poe_die(-1);
-+          }
-+          
-+          if ((filt->stag = malloc (strlen (optarg) + sizeof (struct pppoe_tag))) == NULL) {
-+              poe_error (sess,"failed to malloc for service name: %m");
-+              return (-1);
-+          }
-+          
-+          filt->stag->tag_len = htons (strlen (optarg));
-+          filt->stag->tag_type = PTT_SRV_NAME;
-+          strcpy ((char *) (filt->stag->tag_data), optarg);
-+          break;
-+      default:
-+          poe_error (sess,"Unknown option '%c'", optopt);
-+          print_help ();
-+          return (-1);
-+      }
-+    
-+    
-+    return (1);
-+    
-+}
-+
-+
-+int main(int argc, char** argv){
-+    int ret;
-+    struct filter *filt;
-+    struct session *ses = (struct session *)malloc(sizeof(struct session));
-+    char buf[256];
-+    ses=(void *)malloc(sizeof(struct session));
-+    
-+    if(!ses){
-+      return -1;
-+    }
-+    memset(ses,0,sizeof(struct session));
-+    
-+    
-+    
-+    openlog ("pppoed", LOG_PID | LOG_NDELAY, LOG_PPPOE);
-+    setlogmask (LOG_UPTO (ses->opt_debug ? LOG_DEBUG : LOG_INFO));
-+    
-+    
-+    if ((get_args (argc,(char **) argv,ses)) <1)
-+        poe_die(-1);
-+    
-+    filt=ses->filt;  /* makes the code more readable */
-+    
-+    if (!ses->np) {
-+      poe_create_pidfile (ses);
-+//    signal (SIGINT, &sigproc);
-+//    signal (SIGTERM, &sigproc);
-+      signal (SIGCHLD, &sigchild);
-+    }
-+    
-+    if(ses->type == SESSION_CLIENT){
-+
-+      poe_info(ses,"calling client_init_ses\n");
-+      ret = client_init_ses(ses,ses->name);
-+    
-+      if( ret < 0 ){
-+          return -1;
-+      }
-+
-+      while (ses->filt->num_restart > 0)
-+      {
-+          poe_info(ses,"Restart number %d ",ses->filt->num_restart);
-+          ppp_connect (ses);
-+          ses->filt->num_restart--;
-+      }
-+
-+    }else if( ses->type == SESSION_SERVER ){
-+
-+      poe_info(ses,"calling srv_init_ses\n");
-+      ret = srv_init_ses(ses,ses->name);
-+
-+      if( ret < 0 ){
-+          return -1;
-+      }
-+
-+      ret = 1;
-+      while(ret>=0)
-+          ret = ppp_connect(ses);
-+    
-+    }
-+
-+    
-+    
-+    
-+    poe_info(ses,"ppp_connect came back! %d",ret);
-+    
-+    exit(0);
-+    
-+}
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoefwd.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoefwd.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoefwd.c       Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoefwd.c     Sun Aug  6 11:39:28 2000
-@@ -0,0 +1,61 @@
-+#include "pppoe.h"
-+
-+void fatal (char *fmt, ...)
-+{
-+    va_list pvar;
-+
-+#if defined(__STDC__)
-+    va_start(pvar, fmt);
-+#else
-+    char *fmt;
-+    va_start(pvar);
-+    fmt = va_arg(pvar, char *);
-+#endif
-+
-+    vprintf( fmt, pvar);
-+    va_end(pvar);
-+
-+    exit(1);                  /* as promised */
-+}
-+
-+void info (char *fmt, ...)
-+{
-+    va_list pvar;
-+
-+#if defined(__STDC__)
-+    va_start(pvar, fmt);
-+#else
-+    char *fmt;
-+    va_start(pvar);
-+    fmt = va_arg(pvar, char *);
-+#endif
-+
-+    vprintf( fmt, pvar);
-+    va_end(pvar);
-+
-+}
-+
-+
-+int main(int argc, char** argv){
-+    int ret;
-+    struct session *ses = (struct session *)malloc(sizeof(struct session));
-+
-+    if(!ses) return -1;
-+
-+    ret = relay_init_ses(ses,argv[1],argv[2]);
-+    
-+    if( ret < 0 ){
-+      return -1;
-+    }
-+
-+    ses->log_to_fd = 1;
-+    ses->opt_debug=1;
-+    while(1)
-+      ret = session_connect(ses);
-+    
-+    
-+    
-+    return ret;
-+
-+
-+}
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoehash.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoehash.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoehash.c      Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoehash.c    Sun Aug  6 11:39:28 2000
-@@ -0,0 +1,91 @@
-+/* PPPoE support library "libpppoe"
-+ *
-+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
-+ *              Jamal Hadi Salim <hadi@cyberus.ca>
-+ *
-+ *  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 "pppoe.h"
-+
-+
-+#define PPPOE_HASH_SIZE 16
-+
-+
-+static inline int keycmp(char *a, char *b, int x, int y){
-+    return x==y && !memcmp(a,b,x);
-+}
-+
-+static int hash_con(int key_len, char* key)
-+{
-+    int i = 0;
-+    char hash[sizeof(int)]={0,};
-+
-+    for (i = 0; i < key_len ; ++i)
-+      hash[i% sizeof(int)] = hash[i%sizeof(int)] ^ key[i];
-+
-+    i = (*((int*)hash)) ;
-+    i &= PPPOE_HASH_SIZE - 1;
-+
-+    return i;
-+}     
-+
-+static struct pppoe_con *con_ht[PPPOE_HASH_SIZE] = { 0, };
-+
-+struct pppoe_con *get_con(int len, char *key)
-+{
-+    int hash = hash_con(len, key);
-+    struct pppoe_con *ret;
-+
-+    ret = con_ht[hash];
-+
-+    while (ret && !keycmp(ret->key,key, ret->key_len, len))
-+      ret = ret->next;
-+
-+    return ret;
-+}
-+
-+int store_con(struct pppoe_con *pc)
-+{
-+    int hash = hash_con(pc->key_len, pc->key);
-+    struct pppoe_con *ret;
-+
-+    ret = con_ht[hash];
-+    while (ret) {
-+      if (!keycmp(ret->key, pc->key, ret->key_len, pc->key_len))
-+          return -EALREADY;
-+      
-+      ret = ret->next;
-+    }
-+
-+    if (!ret) {
-+      pc->next = con_ht[hash];
-+      con_ht[hash] = pc;
-+    }
-+
-+    return 0;
-+}
-+
-+struct pppoe_con *delete_con(unsigned long len, char *key)
-+{
-+    int hash = hash_con(len, key);
-+    struct pppoe_con *ret, **src;
-+
-+    ret = con_ht[hash];
-+    src = &con_ht[hash];
-+
-+    while (ret) {
-+      if (keycmp(ret->key,key, ret->key_len, len)) {
-+          *src = ret->next;
-+          break;
-+      }
-+      
-+      src = &ret->next;
-+      ret = ret->next;
-+    }
-+
-+    return ret;
-+}
-+
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/utils.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/utils.c
---- ppp-2.4.1.orig/pppd/plugins/pppoe/utils.c  Wed Dec 31 19:00:00 1969
-+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/utils.c        Sun Aug  6 11:39:28 2000
-@@ -0,0 +1,667 @@
-+
-+/*
-+ * utils.c - various utility functions used in pppoed.
-+ *
-+ * mostly stolen from ppp-2.3.10 by Marc Boucher <marc@mbsi.ca>
-+ *
-+ * Feb 18/2000 Made fully re-entrant (JHS)
-+ *
-+ * Copyright (c) 1999 The Australian National University.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms are permitted
-+ * provided that the above copyright poe_notice and this paragraph are
-+ * duplicated in all such forms and that any documentation,
-+ * advertising materials, and other materials related to such
-+ * distribution and use acknowledge that the software was developed
-+ * by the Australian National University.  The name of the University
-+ * may not be used to endorse or promote products derived from this
-+ * software without specific prior written permission.
-+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-+ */
-+
-+#include <stdio.h>            /* stdio               */
-+#include <stdlib.h>           /* strtoul(), realloc() */
-+#include <string.h>           /* memcpy()             */
-+#include <unistd.h>           /* STDIN_FILENO,exec    */
-+#include <errno.h>            /* errno                */
-+
-+#include <sys/time.h>
-+
-+#include <net/ethernet.h>
-+#include <netinet/in.h>
-+
-+#include <stdarg.h>
-+#include <ctype.h>
-+#include <syslog.h>
-+#include <limits.h>
-+#include <paths.h>
-+
-+#include "pppoe.h"
-+
-+static char pidfilename[PATH_MAX];    /* name of pid file */
-+
-+/*
-+static int detached = 0;
-+   log_to_fd = -1;
-+ */
-+
-+static void vslp_printer (void *, char *,...);
-+static void format_packet (struct pppoe_packet *, int, void (*)(void *, char *,...), void *);
-+static void format_tag (struct pppoe_tag *, void (*)(void *, char *,...), void *);
-+struct buffer_poe_info {
-+  char *ptr;
-+  int len;
-+};
-+
-+void poe_die (int status);
-+
-+
-+/*
-+ * vpoe_slprintf - like vsprintf, except we
-+ * also specify the length of the output buffer, and we handle
-+ * %r (recursive format), %m (poe_error message), %v (visible string),
-+ * %q (quoted string), %t (current time) and %E (Ether address) formats.
-+ * Doesn't do floating-point formats.
-+ * Returns the number of chars put into buf.
-+ */
-+#define OUTCHAR(c)    (buflen > 0? (--buflen, *buf++ = (c)): 0)
-+
-+int
-+vpoe_slprintf (char *buf, int buflen, char *fmt, va_list args)
-+{
-+  int c, i, n;
-+  int width, prec, fillch;
-+  int base, len, neg, quoted;
-+  unsigned long val = 0;
-+  char *str, *f, *buf0;
-+  unsigned char *p;
-+  char num[32];
-+  time_t t;
-+  static char hexchars[] = "0123456789abcdef";
-+  struct buffer_poe_info bufpoe_info;
-+
-+  buf0 = buf;
-+  --buflen;
-+  while (buflen > 0) {
-+    for (f = fmt; *f != '%' && *f != 0; ++f);
-+    if (f > fmt) {
-+      len = f - fmt;
-+      if (len > buflen)
-+      len = buflen;
-+      memcpy (buf, fmt, len);
-+      buf += len;
-+      buflen -= len;
-+      fmt = f;
-+    }
-+    if (*fmt == 0)
-+      break;
-+    c = *++fmt;
-+    width = 0;
-+    prec = -1;
-+    fillch = ' ';
-+    if (c == '0') {
-+      fillch = '0';
-+      c = *++fmt;
-+    }
-+    if (c == '*') {
-+      width = va_arg (args, int);
-+      c = *++fmt;
-+    }
-+    else {
-+      while (isdigit (c)) {
-+      width = width * 10 + c - '0';
-+      c = *++fmt;
-+      }
-+    }
-+    if (c == '.') {
-+      c = *++fmt;
-+      if (c == '*') {
-+      prec = va_arg (args, int);
-+      c = *++fmt;
-+      }
-+      else {
-+      prec = 0;
-+      while (isdigit (c)) {
-+        prec = prec * 10 + c - '0';
-+        c = *++fmt;
-+      }
-+      }
-+    }
-+    str = 0;
-+    base = 0;
-+    neg = 0;
-+    ++fmt;
-+    switch (c) {
-+    case 'd':
-+      i = va_arg (args, int);
-+      if (i < 0) {
-+      neg = 1;
-+      val = -i;
-+      }
-+      else
-+      val = i;
-+      base = 10;
-+      break;
-+    case 'o':
-+      val = va_arg (args, unsigned int);
-+      base = 8;
-+      break;
-+    case 'x':
-+    case 'X':
-+      val = va_arg (args, unsigned int);
-+      base = 16;
-+      break;
-+    case 'p':
-+      val = (unsigned long) va_arg (args, void *);
-+      base = 16;
-+      neg = 2;
-+      break;
-+    case 's':
-+      str = va_arg (args, char *);
-+      break;
-+    case 'c':
-+      num[0] = va_arg (args, int);
-+      num[1] = 0;
-+      str = num;
-+      break;
-+    case 'm':
-+      str = strerror (errno);
-+      break;
-+    case 'E':
-+      p = va_arg (args, unsigned char *);
-+      for (n = ETH_ALEN; n > 0; --n) {
-+      c = *p++;
-+      OUTCHAR (hexchars[(c >> 4) & 0xf]);
-+      OUTCHAR (hexchars[c & 0xf]);
-+      if (n > 1)
-+        OUTCHAR (':');
-+      }
-+      continue;
-+    case 'r':
-+      f = va_arg (args, char *);
-+#ifndef __powerpc__
-+      n = vpoe_slprintf (buf, buflen + 1, f, va_arg (args, va_list));
-+#else
-+      /* On the powerpc, a va_list is an array of 1 structure */
-+      n = vpoe_slprintf (buf, buflen + 1, f, va_arg (args, void *));
-+#endif
-+      buf += n;
-+      buflen -= n;
-+      continue;
-+    case 't':
-+      time (&t);
-+      str = ctime (&t);
-+      str += 4;                       /* chop off the day name */
-+      str[15] = 0;            /* chop off year and newline */
-+      break;
-+    case 'v':                 /* "visible" string */
-+    case 'q':                 /* quoted string */
-+      quoted = c == 'q';
-+      p = va_arg (args, unsigned char *);
-+      if (fillch == '0' && prec >= 0) {
-+      n = prec;
-+      }
-+      else {
-+      n = strlen ((char *) p);
-+      if (prec >= 0 && n > prec)
-+        n = prec;
-+      }
-+      while (n > 0 && buflen > 0) {
-+      c = *p++;
-+      --n;
-+      if (!quoted && c >= 0x80) {
-+        OUTCHAR ('M');
-+        OUTCHAR ('-');
-+        c -= 0x80;
-+      }
-+      if (quoted && (c == '"' || c == '\\'))
-+        OUTCHAR ('\\');
-+      if (c < 0x20 || (0x7f <= c && c < 0xa0)) {
-+        if (quoted) {
-+          OUTCHAR ('\\');
-+          switch (c) {
-+          case '\t':
-+            OUTCHAR ('t');
-+            break;
-+          case '\n':
-+            OUTCHAR ('n');
-+            break;
-+          case '\b':
-+            OUTCHAR ('b');
-+            break;
-+          case '\f':
-+            OUTCHAR ('f');
-+            break;
-+          default:
-+            OUTCHAR ('x');
-+            OUTCHAR (hexchars[c >> 4]);
-+            OUTCHAR (hexchars[c & 0xf]);
-+          }
-+        }
-+        else {
-+          if (c == '\t')
-+            OUTCHAR (c);
-+          else {
-+            OUTCHAR ('^');
-+            OUTCHAR (c ^ 0x40);
-+          }
-+        }
-+      }
-+      else
-+        OUTCHAR (c);
-+      }
-+      continue;
-+    case 'P':                 /* print PPPoE packet */
-+      bufpoe_info.ptr = buf;
-+      bufpoe_info.len = buflen + 1;
-+      p = va_arg (args, unsigned char *);
-+      n = va_arg (args, int);
-+      format_packet ((struct pppoe_packet *) p, n, vslp_printer, &bufpoe_info);
-+      buf = bufpoe_info.ptr;
-+      buflen = bufpoe_info.len - 1;
-+      continue;
-+    case 'T':                 /* print PPPoE tag */
-+      bufpoe_info.ptr = buf;
-+      bufpoe_info.len = buflen + 1;
-+      p = va_arg (args, unsigned char *);
-+      format_tag ((struct pppoe_tag *) p, vslp_printer, &bufpoe_info);
-+      buf = bufpoe_info.ptr;
-+      buflen = bufpoe_info.len - 1;
-+      continue;
-+    case 'B':
-+      p = va_arg (args, unsigned char *);
-+      for (n = prec; n > 0; --n) {
-+      c = *p++;
-+      if (fillch == ' ')
-+        OUTCHAR (' ');
-+      OUTCHAR (hexchars[(c >> 4) & 0xf]);
-+      OUTCHAR (hexchars[c & 0xf]);
-+      }
-+      continue;
-+    default:
-+      *buf++ = '%';
-+      if (c != '%')
-+      --fmt;                  /* so %z outputs %z etc. */
-+      --buflen;
-+      continue;
-+    }
-+    if (base != 0) {
-+      str = num + sizeof (num);
-+      *--str = 0;
-+      while (str > num + neg) {
-+      *--str = hexchars[val % base];
-+      val = val / base;
-+      if (--prec <= 0 && val == 0)
-+        break;
-+      }
-+      switch (neg) {
-+      case 1:
-+      *--str = '-';
-+      break;
-+      case 2:
-+      *--str = 'x';
-+      *--str = '0';
-+      break;
-+      }
-+      len = num + sizeof (num) - 1 - str;
-+    }
-+    else {
-+      len = strlen (str);
-+      if (prec >= 0 && len > prec)
-+      len = prec;
-+    }
-+    if (width > 0) {
-+      if (width > buflen)
-+      width = buflen;
-+      if ((n = width - len) > 0) {
-+      buflen -= n;
-+      for (; n > 0; --n)
-+        *buf++ = fillch;
-+      }
-+    }
-+    if (len > buflen)
-+      len = buflen;
-+    memcpy (buf, str, len);
-+    buf += len;
-+    buflen -= len;
-+  }
-+  *buf = 0;
-+  return buf - buf0;
-+}
-+
-+/*
-+ * vslp_printer - used in processing a %P format
-+ */
-+static void
-+vslp_printer (void *arg, char *fmt,...)
-+{
-+  int n;
-+  va_list pvar;
-+  struct buffer_poe_info *bi;
-+
-+  va_start (pvar, fmt);
-+
-+  bi = (struct buffer_poe_info *) arg;
-+  n = vpoe_slprintf (bi->ptr, bi->len, fmt, pvar);
-+  va_end (pvar);
-+
-+  bi->ptr += n;
-+  bi->len -= n;
-+}
-+
-+/*
-+ * format_packet - make a readable representation of a packet,
-+ * calling `printer(arg, format, ...)' to output it.
-+ */
-+static void
-+format_packet (struct pppoe_packet *p,
-+             int len,
-+             void (*printer) (void *, char *,...),
-+             void *arg)
-+{
-+  struct pppoe_tag *t;
-+
-+  printer (arg, "Ether addr: %E\n", p->addr.sll_addr);
-+
-+  switch ((unsigned) ntohs (p->addr.sll_protocol)) {
-+  case ETH_P_PPPOE_DISC:
-+    printer (arg, " (PPPOE Discovery)\n");
-+    break;
-+  case ETH_P_PPPOE_SESS:
-+    printer (arg, " (PPPOE Session)\n");
-+    break;
-+  }
-+
-+  printer (arg, " PPPoE hdr: ver=0x%01x type=0x%01x code=0x%02x "
-+         "sid=0x%04x length=0x%04x ", (unsigned) p->hdr->ver,
-+         (unsigned) p->hdr->type, (unsigned) p->hdr->code, (unsigned) p->hdr->sid,
-+         (unsigned) ntohs (p->hdr->length));
-+
-+  switch (p->hdr->code) {
-+  case PADI_CODE:
-+    printer (arg, "(PADI)\n");
-+    break;
-+  case PADO_CODE:
-+    printer (arg, "(PADO)\n");
-+    break;
-+  case PADR_CODE:
-+    printer (arg, "(PADR)\n");
-+    break;
-+  case PADS_CODE:
-+    printer (arg, "(PADS)\n");
-+    break;
-+  case PADT_CODE:
-+    printer (arg, "(PADT)\n");
-+    break;
-+  default:
-+    printer (arg, "(Unknown)\n");
-+  }
-+
-+#if 0
-+  if (ntohs (p->addr.sll_protocol) != ETH_P_PPPOE_DISC) {
-+      len = ntohs (p->length);
-+
-+    if (len > 64)
-+      printer (arg, " %.64B ...", (p + 1));
-+    else
-+      printer (arg, " %.*B", len, p + 1);
-+
-+    return;
-+  }
-+#endif
-+
-+  for(t = (struct pppoe_tag *) (&p->hdr->tag);
-+      (t < (struct pppoe_tag *) ((char *) (&p->hdr->tag) + ntohs (p->hdr->length))) &&
-+        ntohs (t->tag_type) != PTT_EOL;
-+      t = (struct pppoe_tag *) ((char *) (t + 1) + ntohs (t->tag_len))) {
-+      format_tag (t, printer, arg);
-+  }
-+}
-+
-+/*
-+ * format_tag - make a readable representation of a tag,
-+ * calling `printer(arg, format, ...)' to output it.
-+ */
-+static void
-+format_tag (struct pppoe_tag *t,
-+             void (*printer) (void *, char *,...),
-+             void *arg)
-+{
-+    printer (arg, " PPPoE tag: type=%04x length=%04x ",
-+           ntohs (t->tag_type), ntohs (t->tag_len));
-+    switch ( t->tag_type ) {
-+    case PTT_EOL:
-+      printer (arg, "(End of list)");
-+      break;
-+    case PTT_SRV_NAME:
-+      printer (arg, "(Service name)");
-+      break;
-+    case PTT_AC_NAME:
-+      printer (arg, "(AC Name)");
-+      break;
-+    case PTT_HOST_UNIQ:
-+      printer (arg, "(Host Uniq)");
-+      break;
-+    case PTT_AC_COOKIE:
-+      printer (arg, "(AC Cookie)");
-+      break;
-+    case PTT_VENDOR:
-+      printer (arg, "(Vendor Specific)");
-+      break;
-+    case PTT_RELAY_SID:
-+      printer (arg, "(Relay Session ID)");
-+      break;
-+    case PTT_SRV_ERR:
-+      printer (arg, "(Service Name Error)");
-+      break;
-+    case PTT_SYS_ERR:
-+      printer (arg, "(AC System Error)");
-+      break;
-+    case PTT_GEN_ERR:
-+      printer (arg, "(Generic Error)");
-+      break;
-+    default:
-+      printer (arg, "(Unknown)");
-+    }
-+    if (ntohs (t->tag_len) > 0)
-+      switch ( t->tag_type ) {
-+      case PTT_SRV_NAME:
-+      case PTT_AC_NAME:
-+      case PTT_SRV_ERR:
-+      case PTT_SYS_ERR:
-+      case PTT_GEN_ERR:       /* ascii data */
-+      {
-+        char *buf;
-+        buf = malloc (ntohs (t->tag_len) + 1);
-+        memset (buf, 0, ntohs (t->tag_len) + 1);
-+        strncpy (buf, (char *) (t + 1), ntohs (t->tag_len));
-+//      buf[ntohs (t->tag_len)] = '\0';
-+        printer (arg, " data (UTF-8): %s", buf);
-+        free (buf);
-+        break;
-+      }
-+
-+      case PTT_HOST_UNIQ:
-+      case PTT_AC_COOKIE:
-+      case PTT_RELAY_SID:
-+      printer (arg, " data (bin): %.*B", ntohs (t->tag_len), (char *) (t + 1));
-+      break;
-+
-+      default:
-+      printer (arg, " unrecognized data");
-+      }
-+}
-+
-+/*
-+ * poe_logit - does the hard work for poe_fatal et al.
-+ */
-+static void
-+poe_logit (struct session *ses,int level, char *fmt, va_list args)
-+{
-+  int n;
-+  char buf[256];
-+
-+  n = vpoe_slprintf (buf, sizeof (buf), fmt, args);
-+  syslog (level, "%s", buf);
-+  if (log_to_fd >= 0 && (level != LOG_DEBUG || ses->opt_debug)) {
-+    if (buf[n - 1] != '\n')
-+      buf[n++] = '\n';
-+    if (write (log_to_fd, buf, n) != n)
-+      log_to_fd = -1;
-+  }
-+}
-+
-+/*
-+ * poe_fatal - log an poe_error message and poe_die horribly.
-+ */
-+void
-+poe_fatal (struct session *ses, char *fmt,...)
-+{
-+  va_list pvar;
-+
-+  va_start (pvar, fmt);
-+
-+  poe_logit (ses,LOG_ERR, fmt, pvar);
-+  va_end (pvar);
-+
-+  poe_die(1);                 /* as promised */
-+}
-+
-+/*
-+ * poe_error - log an poe_error message.
-+ */
-+void
-+poe_error (struct session *ses,char *fmt,...)
-+{
-+  va_list pvar;
-+
-+  va_start (pvar, fmt);
-+
-+  poe_logit (ses,LOG_ERR, fmt, pvar);
-+  va_end (pvar);
-+}
-+
-+/*
-+ * poe_warn - log a poe_warning message.
-+ */
-+void
-+poe_warn (struct session *ses,char *fmt,...)
-+{
-+  va_list pvar;
-+
-+  va_start (pvar, fmt);
-+
-+  poe_logit (ses,LOG_WARNING, fmt, pvar);
-+  va_end (pvar);
-+}
-+
-+#if 0
-+/*
-+ * poe_notice - log a poe_notice-level message.
-+ */
-+void
-+poe_notice (int log_to_fd ,char *fmt,...)
-+{
-+  va_list pvar;
-+
-+  va_start (pvar, fmt);
-+
-+  poe_logit (log_to_fd,LOG_NOTICE, fmt, pvar);
-+  va_end (pvar);
-+}
-+
-+#endif
-+/*
-+ * poe_info - log an poe_informational message.
-+ */
-+void
-+poe_info (struct session *ses,char *fmt,...)
-+{
-+  va_list pvar;
-+
-+  va_start (pvar, fmt);
-+
-+  poe_logit (ses,LOG_INFO, fmt, pvar);
-+  va_end (pvar);
-+}
-+
-+/*
-+ * poe_dbglog - log a debug message.
-+ */
-+void
-+poe_dbglog (struct session *ses ,char *fmt,...)
-+{
-+  va_list pvar;
-+
-+  va_start (pvar, fmt);
-+
-+  poe_logit (ses,LOG_DEBUG, fmt, pvar);
-+  va_end (pvar);
-+}
-+
-+/*
-+ * Create a file containing our process ID.
-+ */
-+void
-+poe_create_pidfile (struct session *ses)
-+{
-+  FILE *pidfile;
-+
-+  sprintf (pidfilename, "%s%s.pid", _PATH_VARRUN, "pppoed");
-+  if ((pidfile = fopen (pidfilename, "w")) != NULL) {
-+    fprintf (pidfile, "%d\n", getpid ());
-+    (void) fclose (pidfile);
-+  }
-+  else {
-+    poe_error (ses,"Failed to create pid file %s: %m", pidfilename);
-+    pidfilename[0] = 0;
-+  }
-+}
-+
-+/*
-+ * detach - detach us from the controlling terminal.
-+ */
-+void
-+poe_detach (struct session *ses)
-+{
-+  if (ses->detached)
-+    return;
-+
-+  if ((daemon (0, 0)) < 0) {
-+    poe_error (ses,"Couldn't detach (daemon failed: %m)");
-+#if 0
-+    poe_die (1);                      /* or just return? */
-+#endif
-+  }
-+  ses->detached = 1;
-+  ses->log_to_fd = -1;
-+  /* update pid files if they have been written already */
-+  if (pidfilename[0])
-+    poe_create_pidfile (ses);
-+}
-+
-+/*
-+ * cleanup - restore anything which needs to be restored before we exit
-+ */
-+/* ARGSUSED */
-+static void
-+cleanup ()
-+{
-+  if (pidfilename[0] != 0 && unlink (pidfilename) < 0 && errno != ENOENT)
-+    syslog (LOG_INFO,"unable to delete pid file ");
-+  pidfilename[0] = 0;
-+}
-+
-+/*
-+ * poe_die - clean up state and exit with the specified status.
-+ */
-+void
-+poe_die (int status)
-+{
-+  cleanup ();
-+  syslog (LOG_INFO, "Exit.");
-+  exit (status);
-+}
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/pppd.h ppp-2.4.1.pppoe2/pppd/pppd.h
---- ppp-2.4.1.orig/pppd/pppd.h Tue Mar 13 00:54:37 2001
-+++ ppp-2.4.1.pppoe2/pppd/pppd.h       Sun Apr  1 15:06:17 2001
-@@ -496,6 +496,8 @@
- int  open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */
- int  tty_establish_ppp __P((int));  /* Turn serial port into a ppp interface */
- void tty_disestablish_ppp __P((int)); /* Restore port to normal operation */
-+void generic_disestablish_ppp __P((int dev_fd)); /* Restore device setting */
-+int  generic_establish_ppp __P((int dev_fd)); /* Make a ppp interface */
- void make_new_bundle __P((int, int, int, int)); /* Create new bundle */
- int  bundle_attach __P((int));        /* Attach link to existing bundle */
- void cfg_bundle __P((int, int, int, int)); /* Configure existing bundle */
-@@ -587,6 +589,7 @@
-                               /* Simplified number_option for decimal ints */
- void add_options __P((option_t *)); /* Add extra options */
- void check_options __P((void));       /* check values after all options parsed */
-+int remove_option __P((char *)); /* Disable the specified option */
- int  override_value __P((const char *, int, const char *));
-                               /* override value if permitted by priority */
- void print_options __P((void (*) __P((void *, char *, ...)), void *));
-diff -r -N -u -b -B ppp-2.4.1.orig/pppd/sys-linux.c ppp-2.4.1.pppoe2/pppd/sys-linux.c
---- ppp-2.4.1.orig/pppd/sys-linux.c    Tue Mar 13 00:54:41 2001
-+++ ppp-2.4.1.pppoe2/pppd/sys-linux.c  Sun Apr  1 15:44:53 2001
-@@ -141,7 +141,7 @@
- static int restore_term        = 0;   /* 1 => we've munged the terminal */
- static struct termios inittermios;    /* Initial TTY termios */
--static int new_style_driver = 0;
-+int new_style_driver = 0;
- static char loop_name[20];
- static unsigned char inbuf[512]; /* buffer for chars read from loopback */
-@@ -352,23 +352,14 @@
-     return (1);
- }
-+
- /********************************************************************
-  *
-- * tty_establish_ppp - Turn the serial port into a ppp interface.
-+ * generic_establish_ppp - Turn the fd into a ppp interface.
-  */
--
--int tty_establish_ppp (int tty_fd)
-+int generic_establish_ppp (int fd)
- {
-     int x;
--    int fd = -1;
--
--/*
-- * Ensure that the tty device is in exclusive mode.
-- */
--    if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
--      if ( ! ok_error ( errno ))
--          warn("Couldn't make tty exclusive: %m");
--    }
- /*
-  * Demand mode - prime the old ppp device to relinquish the unit.
-  */
-@@ -377,26 +368,13 @@
-       error("ioctl(transfer ppp unit): %m");
-       return -1;
-     }
--/*
-- * Set the current tty to the PPP discpline
-- */
--#ifndef N_SYNC_PPP
--#define N_SYNC_PPP 14
--#endif
--    ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
--    if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
--      if ( ! ok_error (errno) ) {
--          error("Couldn't set tty to PPP discipline: %m");
--          return -1;
--      }
--    }
-     if (new_style_driver) {
-       /* Open another instance of /dev/ppp and connect the channel to it */
-       int flags;
--      if (ioctl(tty_fd, PPPIOCGCHAN, &chindex) == -1) {
-+      if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
-           error("Couldn't get channel number: %m");
-           goto err;
-       }
-@@ -440,8 +419,8 @@
-       /*
-        * Old-style driver: find out which interface we were given.
-        */
--      set_ppp_fd (tty_fd);
--      if (ioctl(tty_fd, PPPIOCGUNIT, &x) < 0) {       
-+      set_ppp_fd (fd);
-+      if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
-           if (ok_error (errno))
-               goto err;
-           fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
-@@ -454,9 +433,9 @@
-       /*
-        * Fetch the initial file flags and reset blocking mode on the file.
-        */
--      initfdflags = fcntl(tty_fd, F_GETFL);
-+      initfdflags = fcntl(fd, F_GETFL);
-       if (initfdflags == -1 ||
--          fcntl(tty_fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
-+          fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
-           if ( ! ok_error (errno))
-               warn("Couldn't set device to non-blocking mode: %m");
-       }
-@@ -470,13 +450,6 @@
-     if (!looped)
-       set_kdebugflag (kdebugflag);
--#define SC_RCVB       (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
--#define SC_LOGB       (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
--               | SC_LOG_FLUSH)
--
--    set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB))
--                     | ((kdebugflag * SC_DEBUG) & SC_LOGB)));
--
-     SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
-           driver_version, driver_modification, driver_patch));
-@@ -485,22 +458,86 @@
-  err_close:
-     close(fd);
-  err:
--    if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
-+    if (ioctl(fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
-       warn("Couldn't reset tty to normal line discipline: %m");
-     return -1;
- }
- /********************************************************************
-  *
-- * tty_disestablish_ppp - Restore the serial port to normal operation,
-- * and reconnect the ppp unit to the loopback if in demand mode.
-+ * tty_establish_ppp - Turn the serial port into a ppp interface.
-+ */
-+
-+int tty_establish_ppp (int tty_fd)
-+{
-+    int ret_fd;
-+/*
-+ * Ensure that the tty device is in exclusive mode.
-+ */
-+    if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
-+      if ( ! ok_error ( errno ))
-+          warn("Couldn't make tty exclusive: %m");
-+    }
-+/*
-+ * Set the current tty to the PPP discpline
-+ */
-+
-+#ifndef N_SYNC_PPP
-+#define N_SYNC_PPP 14
-+#endif
-+    ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
-+    if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
-+      if ( ! ok_error (errno) ) {
-+          error("Couldn't set tty to PPP discipline: %m");
-+          return -1;
-+      }
-+    }
-+
-+    ret_fd = generic_establish_ppp(tty_fd);
-+#define SC_RCVB       (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
-+#define SC_LOGB       (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
-+               | SC_LOG_FLUSH)
-+
-+    set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB))
-+                     | ((kdebugflag * SC_DEBUG) & SC_LOGB)));
-+
-+    return ret_fd;
-+}
-+
-+/********************************************************************
-+ *
-+ * generic_disestablish_ppp - Restore device components to normal
-+ * operation, and reconnect the ppp unit to the loopback if in demand
-+ * mode.  This shouldn't call die() because it's called from die().
-+*/
-+void generic_disestablish_ppp(int dev_fd){
-+    /* Restore loop if needed */
-+    if(demand)
-+      restore_loop();
-+
-+    /* Finally detach the device */
-+    initfdflags = -1;
-+
-+    if (new_style_driver) {
-+      close(ppp_fd);
-+      ppp_fd = -1;
-+      if (!looped && ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
-+          error("Couldn't release PPP unit: %m");
-+      if (!multilink)
-+          remove_fd(ppp_dev_fd);
-+    }
-+}
-+
-+/********************************************************************
-+ *
-+ * tty_disestablish_ppp - Restore the serial port to normal operation.
-  * This shouldn't call die() because it's called from die().
-  */
- void tty_disestablish_ppp(int tty_fd)
- {
--    if (demand)
--      restore_loop();
-+    generic_disestablish_ppp(tty_fd);
-+
-     if (!hungup) {
- /*
-  * Flush the tty output buffer so that the TIOCSETD doesn't hang.
-@@ -526,16 +563,6 @@
-               warn("Couldn't restore device fd flags: %m");
-       }
-     }
--    initfdflags = -1;
--
--    if (new_style_driver) {
--      close(ppp_fd);
--      ppp_fd = -1;
--      if (!looped && ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
--          error("Couldn't release PPP unit: %m");
--      if (!multilink)
--          remove_fd(ppp_dev_fd);
--    }
- }
- /*
-@@ -2567,7 +2594,7 @@
-  * Just to be sure, set the real serial port to the normal discipline.
-  */
--static void
-+void
- restore_loop(void)
- {
-     looped = 1;
-diff -r -N -u -b -B ppp-2.4.1.orig/sunos4/Makefile ppp-2.4.1.pppoe2/sunos4/Makefile
---- ppp-2.4.1.orig/sunos4/Makefile     Tue Mar 24 22:09:35 1998
-+++ ppp-2.4.1.pppoe2/sunos4/Makefile   Wed Dec 31 19:00:00 1969
-@@ -1,57 +0,0 @@
--#
--# Makefile for STREAMS modules for SunOS 4.
--#
--# $Id$
--#
--
--include Makedefs
--
--LD = /usr/bin/ld              # make sure we don't get gnu ld
--
--# Defining __$(ARCH)__ is for gcc's broken version of sun/vddrv.h.
--ARCH = `/bin/arch -k`
--DEFINES= -DKERNEL -D_KERNEL -DSUNOS4 -D$(ARCH) -D__$(ARCH)__ \
--       -DDEBUG -DNO_DLPI -DSNIT_SUPPORT
--CFLAGS= $(DEFINES) -I../include $(COPTS)
--
--MODULES= ppp_mod.o ppp_ahdl_mod.o ppp_comp_mod.o if_ppp_mod.o
--
--all:  $(MODULES)
--
--ppp_mod.o:    ppp.o ppp_vdcmd.o
--      $(LD) -r -o ppp_mod.o ppp.o ppp_vdcmd.o
--
--ppp_ahdl_mod.o: ppp_ahdlc.o ppp_ahdlc_vdcmd.o
--      $(LD) -r -o ppp_ahdl_mod.o ppp_ahdlc.o ppp_ahdlc_vdcmd.o
--
--COMP_OBJS = ppp_comp.o bsd-comp.o deflate.o zlib.o vjcompress.o \
--      ppp_comp_vdcmd.o
--ppp_comp_mod.o: $(COMP_OBJS)
--      $(LD) -r -o $@ $(COMP_OBJS)
--
--if_ppp.o: ../modules/if_ppp.c
--      $(CC) $(CFLAGS) -c $?
--bsd-comp.o: ../modules/bsd-comp.c
--      $(CC) $(CFLAGS) -c $?
--deflate.o: ../modules/deflate.c
--      $(CC) $(CFLAGS) -c $?
--ppp.o:        ../modules/ppp.c
--      $(CC) $(CFLAGS) -c $?
--ppp_ahdlc.o: ../modules/ppp_ahdlc.c
--      $(CC) $(CFLAGS) -c $?
--ppp_comp.o: ../modules/ppp_comp.c
--      $(CC) $(CFLAGS) -c $?
--vjcompress.o: ../modules/vjcompress.c
--      $(CC) $(CFLAGS) -c $?
--zlib.o:       ../common/zlib.c
--      $(CC) $(CFLAGS) -c $?
--
--if_ppp_mod.o: if_ppp.o if_ppp_vdcmd.o
--      $(LD) -r -o if_ppp_mod.o if_ppp.o if_ppp_vdcmd.o
--
--install: all
--      $(INSTALL) $(MODULES) $(BINDIR)
--      ./ppp.INSTALL
--
--clean:
--      rm -f ppp ppp_comp ppp_ahdl *.o *~ core
This page took 0.221135 seconds and 4 git commands to generate.