[PATCH] in kernel PPPoE server using pppoe(4)

View: New views
2 Messages — Rating Filter:   Alert me  

[PATCH] in kernel PPPoE server using pppoe(4)

by Динар Талыпов :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

The patch below allows to use pppoe(4) interface in server mode
if kernel is compiled with option PPPOE_SERVER.
Sample configuration of /etc/hostname.pppoe0 is

inet 192.168.3.1 255.255.255.255 NONE link0 \
pppoedev xl0 peerproto chap \
pppoeac test \
pppoesvc test \
peername 'test' peerkey 'test' up
dest 192.168.3.2

This allows to handle incoming pppoe session with username test and password test.
Next I'm planing to implement AAA (authorization, authentication, accounting) socket like route(4)
to handle all these stuff in userland process.

Any help or comments are welcome.

--
Best regards,
Dinar

Index: if_pppoe.h
===================================================================
RCS file: /cvs/src/sys/net/if_pppoe.h,v
retrieving revision 1.4
diff -u -r1.4 if_pppoe.h
--- if_pppoe.h 26 Jun 2008 05:42:20 -0000 1.4
+++ if_pppoe.h 19 Aug 2008 11:16:33 -0000
@@ -71,5 +71,38 @@
 
 void pppoeintr(void);
 
+#ifdef PPPOE_SERVER
+#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
+#endif
+
+struct pppoe_softc {
+ struct sppp sc_sppp; /* contains a struct ifnet as first element */
+ LIST_ENTRY(pppoe_softc) sc_list;
+ struct ifnet *sc_eth_if; /* ethernet interface we are using */
+
+ int sc_state; /* discovery phase or session connected */
+ struct ether_addr sc_dest; /* hardware address of concentrator */
+ u_int16_t sc_session; /* PPPoE session id */
+
+ char *sc_service_name; /* if != NULL: requested name of service */
+ char *sc_concentrator_name; /* if != NULL: requested concentrator id */
+ u_int8_t *sc_ac_cookie; /* content of AC cookie we must echo back */
+ size_t sc_ac_cookie_len; /* length of cookie data */
+ u_int8_t *sc_relay_sid; /* content of relay SID we must echo back */
+ size_t sc_relay_sid_len; /* length of relay SID data */
+#ifdef PPPOE_SERVER
+ u_int8_t *sc_hunique; /* content of host unique we must echo back */
+ size_t sc_hunique_len; /* length of host unique */
+#endif
+ u_int32_t sc_unique; /* our unique id */
+ struct timeout sc_timeout; /* timeout while not in session state */
+ int sc_padi_retried; /* number of PADI retries already done */
+ int sc_padr_retried; /* number of PADR retries already done */
+
+ struct timeval sc_session_time; /* time the session was established */
+};
+
+
+
 #endif /* _KERNEL */
 #endif /* _NET_IF_PPPOE_H_ */
Index: if_pppoe.c
===================================================================
RCS file: /cvs/src/sys/net/if_pppoe.c,v
retrieving revision 1.23
diff -u -r1.23 if_pppoe.c
--- if_pppoe.c 9 Aug 2008 11:25:05 -0000 1.23
+++ if_pppoe.c 19 Aug 2008 11:24:00 -0000
@@ -47,10 +47,12 @@
 #include <net/if.h>
 #include <net/if_types.h>
 #include <net/if_sppp.h>
-#include <net/if_pppoe.h>
-#include <net/netisr.h>
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
+#include <net/if_pppoe.h>
+#include <net/netisr.h>
+
+
 
 /* for arc4random() */
 #include <dev/rndvar.h>
@@ -116,36 +118,6 @@
 #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */
 #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */
 
-#ifdef PPPOE_SERVER
-#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
-#endif
-
-struct pppoe_softc {
- struct sppp sc_sppp; /* contains a struct ifnet as first element */
- LIST_ENTRY(pppoe_softc) sc_list;
- struct ifnet *sc_eth_if; /* ethernet interface we are using */
-
- int sc_state; /* discovery phase or session connected */
- struct ether_addr sc_dest; /* hardware address of concentrator */
- u_int16_t sc_session; /* PPPoE session id */
-
- char *sc_service_name; /* if != NULL: requested name of service */
- char *sc_concentrator_name; /* if != NULL: requested concentrator id */
- u_int8_t *sc_ac_cookie; /* content of AC cookie we must echo back */
- size_t sc_ac_cookie_len; /* length of cookie data */
- u_int8_t *sc_relay_sid; /* content of relay SID we must echo back */
- size_t sc_relay_sid_len; /* length of relay SID data */
-#ifdef PPPOE_SERVER
- u_int8_t *sc_hunique; /* content of host unique we must echo back */
- size_t sc_hunique_len; /* length of host unique */
-#endif
- u_int32_t sc_unique; /* our unique id */
- struct timeout sc_timeout; /* timeout while not in session state */
- int sc_padi_retried; /* number of PADI retries already done */
- int sc_padr_retried; /* number of PADR retries already done */
-
- struct timeval sc_session_time; /* time the session was established */
-};
 
 /* incoming traffic will be queued here */
 struct ifqueue ppoediscinq = { NULL };
@@ -160,6 +132,7 @@
 
 /* management routines */
 void pppoeattach(int);
+
 static int  pppoe_connect(struct pppoe_softc *);
 static int  pppoe_disconnect(struct pppoe_softc *);
 static void pppoe_abort_connect(struct pppoe_softc *);
@@ -595,7 +568,6 @@
  memcpy(&sc->sc_dest, eh->ether_shost, sizeof(sc->sc_dest));
  sc->sc_state = PPPOE_STATE_PADO_SENT;
  pppoe_send_pado(sc);
-
  break;
 #endif /* PPPOE_SERVER */
  case PPPOE_CODE_PADR:
@@ -1250,7 +1222,6 @@
 
  /* notify upper layer */
  sc->sc_sppp.pp_down(&sc->sc_sppp);
-
  splx(x);
 
  return (err);
@@ -1368,7 +1339,7 @@
  struct mbuf *m0;
  size_t len;
  u_int8_t *p;
-
+
  if (sc->sc_state != PPPOE_STATE_PADO_SENT)
  return (EIO);
 
@@ -1379,6 +1350,14 @@
  /* include hunique */
  len += 2 + 2 + sc->sc_hunique_len;
 
+ if (sc->sc_concentrator_name!=NULL){
+    /* include ac_name */
+    len += 2 + 2 + sizeof(sc->sc_concentrator_name);
+    if (sc->sc_service_name!=NULL)
+        /* include service_name */
+        len += 2 + 2 + sizeof(sc->sc_service_name);
+ }
+
  m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
  if (m0 == NULL)
  return (ENOBUFS);
@@ -1387,12 +1366,27 @@
  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
  PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
  PPPOE_ADD_16(p, sizeof(sc->sc_unique));
- memcpy(p, &sc, sizeof(sc->sc_unique));
+ memcpy(p, &sc->sc_unique, sizeof(sc->sc_unique));
+
  p += sizeof(sc->sc_unique);
  PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
  PPPOE_ADD_16(p, sc->sc_hunique_len);
  memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
 
+ if (sc->sc_concentrator_name!=NULL){
+ p += sc->sc_hunique_len;
+ PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
+ PPPOE_ADD_16(p, sizeof(sc->sc_concentrator_name));
+ memcpy(p, sc->sc_concentrator_name, sizeof(sc->sc_concentrator_name));
+
+ if (sc->sc_service_name!=NULL){
+    p += sizeof(sc->sc_concentrator_name);
+    PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
+    PPPOE_ADD_16(p, sizeof(sc->sc_service_name));
+    memcpy(p, sc->sc_service_name, sizeof(sc->sc_service_name));
+ }
+ }
+
  return (pppoe_output(sc, m0));
 }
 
@@ -1403,12 +1397,14 @@
  struct mbuf *m0;
  size_t len, l1;
  u_int8_t *p;
+ struct timeval tv;
 
  if (sc->sc_state != PPPOE_STATE_PADO_SENT)
  return (EIO);
-
- sc->sc_session = mono_time.tv_sec % 0xff + 1;
-
+ getmicrotime(&tv);
+ sc->sc_session = tv.tv_sec % 0xff + 1;
+ sc->sc_session_time.tv_sec = tv.tv_sec;
+ sc->sc_session_time.tv_usec = tv.tv_usec;
  /* calc length */
  len = 0;
  /* include hunique */
@@ -1465,6 +1461,11 @@
  * function and defer disconnecting to the timeout handler.
  */
  sc->sc_state = PPPOE_STATE_CLOSING;
+#ifdef PPPOE_SERVER
+ /* notify upper layer */
+ if (sp->pp_if.if_flags & IFF_PASSIVE)
+ sc->sc_sppp.pp_down(&sc->sc_sppp);
+#endif
  timeout_add(&sc->sc_timeout, hz / 50);
 }
 
Index: if_spppsubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_spppsubr.c,v
retrieving revision 1.70
diff -u -r1.70 if_spppsubr.c
--- if_spppsubr.c 9 Jun 2008 07:07:16 -0000 1.70
+++ if_spppsubr.c 19 Aug 2008 11:34:41 -0000
@@ -90,6 +90,10 @@
 
 #include <net/if_sppp.h>
 
+#ifdef PPPOE_SERVER
+#include <net/if_pppoe.h>
+#endif /* PPPOE_SERVER */
+
 #if defined (__FreeBSD__)
 # define UNTIMEOUT(fun, arg, handle) \
  untimeout(fun, arg, handle)
@@ -141,6 +145,7 @@
 #define PPP_CHAP 0xc223 /* Challenge-Handshake Auth Protocol */
 #define PPP_IPCP 0x8021 /* Internet Protocol Control Protocol */
 #define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
+#define PPP_CCP 0x80fd /* Compression Control Protol */
 
 #define CONF_REQ 1 /* PPP configure request */
 #define CONF_ACK 2 /* PPP configure acknowledge */
@@ -560,6 +565,7 @@
  goto drop;
  }
  switch (ntohs (h->protocol)) {
+ case PPP_CCP:
  default:
  if (sp->state[IDX_LCP] == STATE_OPENED)
  sppp_cp_send (sp, PPP_LCP, PROTO_REJ,
@@ -1136,7 +1142,7 @@
 }
 
 
- /*
+/*
  * Cisco framing implementation.
  */
 
@@ -1268,7 +1274,7 @@
  ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes;
 }
 
- /*
+/*
  * PPP protocol implementation.
  */
 
@@ -1539,6 +1545,11 @@
  log(LOG_DEBUG, SPP_FMT "%s send terminate-ack\n",
     SPP_ARGS(ifp), cp->name);
  sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);
+#ifdef PPPOE_SERVER
+ sp->rst_counter[cp->protoidx] = 0;
+ sppp_cp_change_state(cp, sp, STATE_CLOSING);
+ (cp->tlf)(sp);
+#endif /* PPPOE_SERVER */
  break;
  case STATE_OPENED:
  sp->rst_counter[cp->protoidx] = 0;
@@ -1818,6 +1829,12 @@
  (cp->tls)(sp);
  break;
  case STATE_STARTING:
+#ifdef PPPOE_SERVER
+ if (sp->pp_if.if_flags & IFF_PASSIVE){
+ sppp_cp_change_state(cp, sp, STATE_STARTING);
+ (cp->tls)(sp);
+ }
+#endif
  break;
  case STATE_CLOSED:
  sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
@@ -2117,6 +2134,12 @@
  else
  sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO);
  sp->pp_flags &= ~PP_NEEDAUTH;
+#ifdef PPPOE_SERVER
+ if (sp->pp_if.if_flags & IFF_PASSIVE){
+ sp->lcp.opts |= (1 << LCP_OPT_AUTH_PROTO);
+/* sp->pp_flags |= PP_NEEDAUTH; */
+ }
+#endif
  sppp_open_event(&lcp, sp);
 }
 
@@ -2393,7 +2416,7 @@
  break;
  }
  if (debug)
- addlog("[access denied]\n");
+ addlog("[access denied: No authentication]\n");
  lcp.Close(sp);
  break;
  }
@@ -2472,7 +2495,7 @@
  * deny.
  */
  if (debug)
- addlog("[access denied]\n");
+ addlog("[access denied: Auth method mismatch]\n");
  lcp.Close(sp);
  break;
  }
@@ -2617,7 +2640,16 @@
  }
 
  if (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) {
+#ifdef PPPOE_SERVER
+ if(sp->pp_if.if_flags & IFF_PASSIVE)
+ authproto = sp->myauth.proto = sp->hisauth.proto;
+ else
+ authproto = sp->hisauth.proto;
+#else
  authproto = sp->hisauth.proto;
+#endif
+
+
  opt[i++] = LCP_OPT_AUTH_PROTO;
  opt[i++] = authproto == PPP_CHAP? 5: 4;
  opt[i++] = authproto >> 8;
@@ -3051,6 +3083,10 @@
  sp->ipcp.flags |= IPCP_MYADDR_DYN;
  sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
  }
+#ifdef PPPOE_SERVER
+ if(sp->pp_if.if_flags & IFF_PASSIVE)
+ sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
+#endif
  if (hisaddr == 1) {
  /*
  * XXX - remove this hack!
@@ -3844,6 +3880,7 @@
  sppp_print_string(sp->hisauth.name,
   sppp_strnlen(sp->hisauth.name, AUTHNAMELEN));
  addlog("\n");
+ goto bad;
  }
  if (debug) {
  log(LOG_DEBUG, SPP_FMT "chap input(%s) "
@@ -3880,7 +3917,7 @@
  if (value_len != sizeof digest ||
     bcmp(digest, value, value_len) != 0) {
  /* action scn, tld */
- sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident,
+bad: sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident,
        sizeof(FAILMSG) - 1, (u_char *)FAILMSG,
        0);
  chap.tld(sp);


Re: [PATCH] in kernel PPPoE server using pppoe(4)

by Claudio Jeker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Aug 19, 2008 at 04:01:15PM +0400, Dinar Talypov wrote:

> Hi,
>
> The patch below allows to use pppoe(4) interface in server mode
> if kernel is compiled with option PPPOE_SERVER.
> Sample configuration of /etc/hostname.pppoe0 is
>
> inet 192.168.3.1 255.255.255.255 NONE link0 \
> pppoedev xl0 peerproto chap \
> pppoeac test \
> pppoesvc test \
> peername 'test' peerkey 'test' up
> dest 192.168.3.2
>
> This allows to handle incoming pppoe session with username test and password test.
> Next I'm planing to implement AAA (authorization, authentication, accounting) socket like route(4)
> to handle all these stuff in userland process.
>
> Any help or comments are welcome.
>

WOW! In a way cool but IMO it would be way better to split the data and
control plane of sppp and move the control plane (lcp, ipcp and friends)
to userland. Doing so you could easily do AAA in that deamon.
I'm no big fan of all that sppp code munching packets inside the kernel.

I try to have a look at your code
--
:wq Claudio

> --
> Best regards,
> Dinar
>
> Index: if_pppoe.h
> ===================================================================
> RCS file: /cvs/src/sys/net/if_pppoe.h,v
> retrieving revision 1.4
> diff -u -r1.4 if_pppoe.h
> --- if_pppoe.h 26 Jun 2008 05:42:20 -0000 1.4
> +++ if_pppoe.h 19 Aug 2008 11:16:33 -0000
> @@ -71,5 +71,38 @@
>  
>  void pppoeintr(void);
>  
> +#ifdef PPPOE_SERVER
> +#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
> +#endif
> +
> +struct pppoe_softc {
> + struct sppp sc_sppp; /* contains a struct ifnet as first element */
> + LIST_ENTRY(pppoe_softc) sc_list;
> + struct ifnet *sc_eth_if; /* ethernet interface we are using */
> +
> + int sc_state; /* discovery phase or session connected */
> + struct ether_addr sc_dest; /* hardware address of concentrator */
> + u_int16_t sc_session; /* PPPoE session id */
> +
> + char *sc_service_name; /* if != NULL: requested name of service */
> + char *sc_concentrator_name; /* if != NULL: requested concentrator id */
> + u_int8_t *sc_ac_cookie; /* content of AC cookie we must echo back */
> + size_t sc_ac_cookie_len; /* length of cookie data */
> + u_int8_t *sc_relay_sid; /* content of relay SID we must echo back */
> + size_t sc_relay_sid_len; /* length of relay SID data */
> +#ifdef PPPOE_SERVER
> + u_int8_t *sc_hunique; /* content of host unique we must echo back */
> + size_t sc_hunique_len; /* length of host unique */
> +#endif
> + u_int32_t sc_unique; /* our unique id */
> + struct timeout sc_timeout; /* timeout while not in session state */
> + int sc_padi_retried; /* number of PADI retries already done */
> + int sc_padr_retried; /* number of PADR retries already done */
> +
> + struct timeval sc_session_time; /* time the session was established */
> +};
> +
> +
> +
>  #endif /* _KERNEL */
>  #endif /* _NET_IF_PPPOE_H_ */
> Index: if_pppoe.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_pppoe.c,v
> retrieving revision 1.23
> diff -u -r1.23 if_pppoe.c
> --- if_pppoe.c 9 Aug 2008 11:25:05 -0000 1.23
> +++ if_pppoe.c 19 Aug 2008 11:24:00 -0000
> @@ -47,10 +47,12 @@
>  #include <net/if.h>
>  #include <net/if_types.h>
>  #include <net/if_sppp.h>
> -#include <net/if_pppoe.h>
> -#include <net/netisr.h>
>  #include <netinet/in.h>
>  #include <netinet/if_ether.h>
> +#include <net/if_pppoe.h>
> +#include <net/netisr.h>
> +
> +
>  
>  /* for arc4random() */
>  #include <dev/rndvar.h>
> @@ -116,36 +118,6 @@
>  #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */
>  #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */
>  
> -#ifdef PPPOE_SERVER
> -#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
> -#endif
> -
> -struct pppoe_softc {
> - struct sppp sc_sppp; /* contains a struct ifnet as first element */
> - LIST_ENTRY(pppoe_softc) sc_list;
> - struct ifnet *sc_eth_if; /* ethernet interface we are using */
> -
> - int sc_state; /* discovery phase or session connected */
> - struct ether_addr sc_dest; /* hardware address of concentrator */
> - u_int16_t sc_session; /* PPPoE session id */
> -
> - char *sc_service_name; /* if != NULL: requested name of service */
> - char *sc_concentrator_name; /* if != NULL: requested concentrator id */
> - u_int8_t *sc_ac_cookie; /* content of AC cookie we must echo back */
> - size_t sc_ac_cookie_len; /* length of cookie data */
> - u_int8_t *sc_relay_sid; /* content of relay SID we must echo back */
> - size_t sc_relay_sid_len; /* length of relay SID data */
> -#ifdef PPPOE_SERVER
> - u_int8_t *sc_hunique; /* content of host unique we must echo back */
> - size_t sc_hunique_len; /* length of host unique */
> -#endif
> - u_int32_t sc_unique; /* our unique id */
> - struct timeout sc_timeout; /* timeout while not in session state */
> - int sc_padi_retried; /* number of PADI retries already done */
> - int sc_padr_retried; /* number of PADR retries already done */
> -
> - struct timeval sc_session_time; /* time the session was established */
> -};
>  
>  /* incoming traffic will be queued here */
>  struct ifqueue ppoediscinq = { NULL };
> @@ -160,6 +132,7 @@
>  
>  /* management routines */
>  void pppoeattach(int);
> +
>  static int  pppoe_connect(struct pppoe_softc *);
>  static int  pppoe_disconnect(struct pppoe_softc *);
>  static void pppoe_abort_connect(struct pppoe_softc *);
> @@ -595,7 +568,6 @@
>   memcpy(&sc->sc_dest, eh->ether_shost, sizeof(sc->sc_dest));
>   sc->sc_state = PPPOE_STATE_PADO_SENT;
>   pppoe_send_pado(sc);
> -
>   break;
>  #endif /* PPPOE_SERVER */
>   case PPPOE_CODE_PADR:
> @@ -1250,7 +1222,6 @@
>  
>   /* notify upper layer */
>   sc->sc_sppp.pp_down(&sc->sc_sppp);
> -
>   splx(x);
>  
>   return (err);
> @@ -1368,7 +1339,7 @@
>   struct mbuf *m0;
>   size_t len;
>   u_int8_t *p;
> -
> +
>   if (sc->sc_state != PPPOE_STATE_PADO_SENT)
>   return (EIO);
>  
> @@ -1379,6 +1350,14 @@
>   /* include hunique */
>   len += 2 + 2 + sc->sc_hunique_len;
>  
> + if (sc->sc_concentrator_name!=NULL){
> +    /* include ac_name */
> +    len += 2 + 2 + sizeof(sc->sc_concentrator_name);
> +    if (sc->sc_service_name!=NULL)
> +        /* include service_name */
> +        len += 2 + 2 + sizeof(sc->sc_service_name);
> + }
> +
>   m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
>   if (m0 == NULL)
>   return (ENOBUFS);
> @@ -1387,12 +1366,27 @@
>   PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
>   PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
>   PPPOE_ADD_16(p, sizeof(sc->sc_unique));
> - memcpy(p, &sc, sizeof(sc->sc_unique));
> + memcpy(p, &sc->sc_unique, sizeof(sc->sc_unique));
> +
>   p += sizeof(sc->sc_unique);
>   PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
>   PPPOE_ADD_16(p, sc->sc_hunique_len);
>   memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
>  
> + if (sc->sc_concentrator_name!=NULL){
> + p += sc->sc_hunique_len;
> + PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
> + PPPOE_ADD_16(p, sizeof(sc->sc_concentrator_name));
> + memcpy(p, sc->sc_concentrator_name, sizeof(sc->sc_concentrator_name));
> +
> + if (sc->sc_service_name!=NULL){
> +    p += sizeof(sc->sc_concentrator_name);
> +    PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
> +    PPPOE_ADD_16(p, sizeof(sc->sc_service_name));
> +    memcpy(p, sc->sc_service_name, sizeof(sc->sc_service_name));
> + }
> + }
> +
>   return (pppoe_output(sc, m0));
>  }
>  
> @@ -1403,12 +1397,14 @@
>   struct mbuf *m0;
>   size_t len, l1;
>   u_int8_t *p;
> + struct timeval tv;
>  
>   if (sc->sc_state != PPPOE_STATE_PADO_SENT)
>   return (EIO);
> -
> - sc->sc_session = mono_time.tv_sec % 0xff + 1;
> -
> + getmicrotime(&tv);
> + sc->sc_session = tv.tv_sec % 0xff + 1;
> + sc->sc_session_time.tv_sec = tv.tv_sec;
> + sc->sc_session_time.tv_usec = tv.tv_usec;
>   /* calc length */
>   len = 0;
>   /* include hunique */
> @@ -1465,6 +1461,11 @@
>   * function and defer disconnecting to the timeout handler.
>   */
>   sc->sc_state = PPPOE_STATE_CLOSING;
> +#ifdef PPPOE_SERVER
> + /* notify upper layer */
> + if (sp->pp_if.if_flags & IFF_PASSIVE)
> + sc->sc_sppp.pp_down(&sc->sc_sppp);
> +#endif
>   timeout_add(&sc->sc_timeout, hz / 50);
>  }
>  
> Index: if_spppsubr.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_spppsubr.c,v
> retrieving revision 1.70
> diff -u -r1.70 if_spppsubr.c
> --- if_spppsubr.c 9 Jun 2008 07:07:16 -0000 1.70
> +++ if_spppsubr.c 19 Aug 2008 11:34:41 -0000
> @@ -90,6 +90,10 @@
>  
>  #include <net/if_sppp.h>
>  
> +#ifdef PPPOE_SERVER
> +#include <net/if_pppoe.h>
> +#endif /* PPPOE_SERVER */
> +
>  #if defined (__FreeBSD__)
>  # define UNTIMEOUT(fun, arg, handle) \
>   untimeout(fun, arg, handle)
> @@ -141,6 +145,7 @@
>  #define PPP_CHAP 0xc223 /* Challenge-Handshake Auth Protocol */
>  #define PPP_IPCP 0x8021 /* Internet Protocol Control Protocol */
>  #define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
> +#define PPP_CCP 0x80fd /* Compression Control Protol */
>  
>  #define CONF_REQ 1 /* PPP configure request */
>  #define CONF_ACK 2 /* PPP configure acknowledge */
> @@ -560,6 +565,7 @@
>   goto drop;
>   }
>   switch (ntohs (h->protocol)) {
> + case PPP_CCP:
>   default:
>   if (sp->state[IDX_LCP] == STATE_OPENED)
>   sppp_cp_send (sp, PPP_LCP, PROTO_REJ,
> @@ -1136,7 +1142,7 @@
>  }
>  
>  
> - /*
> +/*
>   * Cisco framing implementation.
>   */
>  
> @@ -1268,7 +1274,7 @@
>   ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes;
>  }
>  
> - /*
> +/*
>   * PPP protocol implementation.
>   */
>  
> @@ -1539,6 +1545,11 @@
>   log(LOG_DEBUG, SPP_FMT "%s send terminate-ack\n",
>      SPP_ARGS(ifp), cp->name);
>   sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);
> +#ifdef PPPOE_SERVER
> + sp->rst_counter[cp->protoidx] = 0;
> + sppp_cp_change_state(cp, sp, STATE_CLOSING);
> + (cp->tlf)(sp);
> +#endif /* PPPOE_SERVER */
>   break;
>   case STATE_OPENED:
>   sp->rst_counter[cp->protoidx] = 0;
> @@ -1818,6 +1829,12 @@
>   (cp->tls)(sp);
>   break;
>   case STATE_STARTING:
> +#ifdef PPPOE_SERVER
> + if (sp->pp_if.if_flags & IFF_PASSIVE){
> + sppp_cp_change_state(cp, sp, STATE_STARTING);
> + (cp->tls)(sp);
> + }
> +#endif
>   break;
>   case STATE_CLOSED:
>   sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
> @@ -2117,6 +2134,12 @@
>   else
>   sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO);
>   sp->pp_flags &= ~PP_NEEDAUTH;
> +#ifdef PPPOE_SERVER
> + if (sp->pp_if.if_flags & IFF_PASSIVE){
> + sp->lcp.opts |= (1 << LCP_OPT_AUTH_PROTO);
> +/* sp->pp_flags |= PP_NEEDAUTH; */
> + }
> +#endif
>   sppp_open_event(&lcp, sp);
>  }
>  
> @@ -2393,7 +2416,7 @@
>   break;
>   }
>   if (debug)
> - addlog("[access denied]\n");
> + addlog("[access denied: No authentication]\n");
>   lcp.Close(sp);
>   break;
>   }
> @@ -2472,7 +2495,7 @@
>   * deny.
>   */
>   if (debug)
> - addlog("[access denied]\n");
> + addlog("[access denied: Auth method mismatch]\n");
>   lcp.Close(sp);
>   break;
>   }
> @@ -2617,7 +2640,16 @@
>   }
>  
>   if (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) {
> +#ifdef PPPOE_SERVER
> + if(sp->pp_if.if_flags & IFF_PASSIVE)
> + authproto = sp->myauth.proto = sp->hisauth.proto;
> + else
> + authproto = sp->hisauth.proto;
> +#else
>   authproto = sp->hisauth.proto;
> +#endif
> +
> +
>   opt[i++] = LCP_OPT_AUTH_PROTO;
>   opt[i++] = authproto == PPP_CHAP? 5: 4;
>   opt[i++] = authproto >> 8;
> @@ -3051,6 +3083,10 @@
>   sp->ipcp.flags |= IPCP_MYADDR_DYN;
>   sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
>   }
> +#ifdef PPPOE_SERVER
> + if(sp->pp_if.if_flags & IFF_PASSIVE)
> + sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
> +#endif
>   if (hisaddr == 1) {
>   /*
>   * XXX - remove this hack!
> @@ -3844,6 +3880,7 @@
>   sppp_print_string(sp->hisauth.name,
>    sppp_strnlen(sp->hisauth.name, AUTHNAMELEN));
>   addlog("\n");
> + goto bad;
>   }
>   if (debug) {
>   log(LOG_DEBUG, SPP_FMT "chap input(%s) "
> @@ -3880,7 +3917,7 @@
>   if (value_len != sizeof digest ||
>      bcmp(digest, value, value_len) != 0) {
>   /* action scn, tld */
> - sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident,
> +bad: sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident,
>         sizeof(FAILMSG) - 1, (u_char *)FAILMSG,
>         0);
>   chap.tld(sp);

LightInTheBox - Buy quality products at wholesale price!