root/net/if_pppoe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pppoeattach
  2. pppoe_clone_create
  3. pppoe_clone_destroy
  4. pppoe_find_softc_by_session
  5. pppoe_find_softc_by_hunique
  6. pppoeintr
  7. pppoe_dispatch_disc_pkt
  8. pppoe_disc_input
  9. pppoe_data_input
  10. pppoe_output
  11. pppoe_ioctl
  12. pppoe_get_mbuf
  13. pppoe_send_padi
  14. pppoe_timeout
  15. pppoe_connect
  16. pppoe_disconnect
  17. pppoe_abort_connect
  18. pppoe_send_padr
  19. pppoe_send_padt
  20. pppoe_send_pado
  21. pppoe_send_pads
  22. pppoe_tls
  23. pppoe_tlf
  24. pppoe_start

    1 /* $OpenBSD: if_pppoe.c,v 1.12 2007/05/28 06:31:01 mcbride Exp $ */
    2 /* $NetBSD: if_pppoe.c,v 1.51 2003/11/28 08:56:48 keihan Exp $ */
    3 
    4 /*
    5  * Copyright (c) 2002 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Martin Husemann <martin@NetBSD.org>.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *        This product includes software developed by the NetBSD
   22  *        Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 /*
   42 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.51 2003/11/28 08:56:48 keihan Exp $");
   43 */
   44 
   45 #include "pppoe.h"
   46 #include "bpfilter.h"
   47 
   48 #include <sys/param.h>
   49 #include <sys/systm.h>
   50 #include <sys/kernel.h>
   51 #include <sys/types.h>
   52 #include <sys/timeout.h>
   53 #include <sys/malloc.h>
   54 #include <sys/mbuf.h>
   55 #include <sys/socket.h>
   56 #include <sys/syslog.h>
   57 #include <sys/proc.h>
   58 #include <sys/ioctl.h>
   59 #include <net/if.h>
   60 #include <net/if_types.h>
   61 #include <net/if_sppp.h>
   62 #include <net/if_pppoe.h>
   63 #include <net/netisr.h>
   64 #include <netinet/in.h>
   65 #include <netinet/if_ether.h>
   66 
   67 /* for arc4random() */
   68 #include <dev/rndvar.h>
   69 
   70 #if NBPFILTER > 0
   71 #include <net/bpf.h>
   72 #endif
   73 
   74 #undef PPPOE_DEBUG      /* XXX - remove this or make it an option */
   75 
   76 #define PPPOEDEBUG(a)   ((sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) ? printf a : 0)
   77 
   78 struct pppoehdr {
   79         u_int8_t vertype;
   80         u_int8_t code;
   81         u_int16_t session;
   82         u_int16_t plen;
   83 } __packed;
   84 
   85 struct pppoetag {
   86         u_int16_t tag;
   87         u_int16_t len;
   88 } __packed;
   89 
   90 #define PPPOE_HEADERLEN         sizeof(struct pppoehdr)
   91 #define PPPOE_VERTYPE           0x11            /* VER=1, TYPE = 1 */
   92 
   93 #define PPPOE_TAG_EOL           0x0000          /* end of list */
   94 #define PPPOE_TAG_SNAME         0x0101          /* service name */
   95 #define PPPOE_TAG_ACNAME        0x0102          /* access concentrator name */
   96 #define PPPOE_TAG_HUNIQUE       0x0103          /* host unique */
   97 #define PPPOE_TAG_ACCOOKIE      0x0104          /* AC cookie */
   98 #define PPPOE_TAG_VENDOR        0x0105          /* vendor specific */
   99 #define PPPOE_TAG_RELAYSID      0x0110          /* relay session id */
  100 #define PPPOE_TAG_SNAME_ERR     0x0201          /* service name error */
  101 #define PPPOE_TAG_ACSYS_ERR     0x0202          /* AC system error */
  102 #define PPPOE_TAG_GENERIC_ERR   0x0203          /* gerneric error */
  103 
  104 #define PPPOE_CODE_PADI         0x09            /* Active Discovery Initiation */
  105 #define PPPOE_CODE_PADO         0x07            /* Active Discovery Offer */
  106 #define PPPOE_CODE_PADR         0x19            /* Active Discovery Request */
  107 #define PPPOE_CODE_PADS         0x65            /* Active Discovery Session confirmation */
  108 #define PPPOE_CODE_PADT         0xA7            /* Active Discovery Terminate */
  109 
  110 /* two byte PPP protocol discriminator, then IP data */
  111 #define PPPOE_MAXMTU    (ETHERMTU - PPPOE_HEADERLEN - 2)
  112 
  113 /* Add a 16 bit unsigned value to a buffer pointed to by PTR */
  114 #define PPPOE_ADD_16(PTR, VAL)                  \
  115                 *(PTR)++ = (VAL) / 256;         \
  116                 *(PTR)++ = (VAL) % 256
  117 
  118 /* Add a complete PPPoE header to the buffer pointed to by PTR */
  119 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN)  \
  120                 *(PTR)++ = PPPOE_VERTYPE;       \
  121                 *(PTR)++ = (CODE);              \
  122                 PPPOE_ADD_16(PTR, SESS);        \
  123                 PPPOE_ADD_16(PTR, LEN)
  124 
  125 #define PPPOE_DISC_TIMEOUT      (hz*5)  /* base for quick timeout calculation */
  126 #define PPPOE_SLOW_RETRY        (hz*60) /* persistent retry interval */
  127 #define PPPOE_DISC_MAXPADI      4       /* retry PADI four times (quickly) */
  128 #define PPPOE_DISC_MAXPADR      2       /* retry PADR twice */
  129 
  130 #ifdef PPPOE_SERVER
  131 #define IFF_PASSIVE     IFF_LINK0       /* wait passively for connection */
  132 #endif
  133 
  134 struct pppoe_softc {
  135         struct sppp sc_sppp;            /* contains a struct ifnet as first element */
  136         LIST_ENTRY(pppoe_softc) sc_list;
  137         struct ifnet *sc_eth_if;        /* ethernet interface we are using */
  138 
  139         int sc_state;                   /* discovery phase or session connected */
  140         struct ether_addr sc_dest;      /* hardware address of concentrator */
  141         u_int16_t sc_session;           /* PPPoE session id */
  142 
  143         char *sc_service_name;          /* if != NULL: requested name of service */
  144         char *sc_concentrator_name;     /* if != NULL: requested concentrator id */
  145         u_int8_t *sc_ac_cookie;         /* content of AC cookie we must echo back */
  146         size_t sc_ac_cookie_len;        /* length of cookie data */
  147 #ifdef PPPOE_SERVER
  148         u_int8_t *sc_hunique;           /* content of host unique we must echo back */
  149         size_t sc_hunique_len;          /* length of host unique */
  150 #endif
  151         u_int32_t sc_unique;            /* our unique id */
  152         struct timeout sc_timeout;      /* timeout while not in session state */
  153         int sc_padi_retried;            /* number of PADI retries already done */
  154         int sc_padr_retried;            /* number of PADR retries already done */
  155 
  156         struct timeval sc_session_time; /* time the session was established */
  157 };
  158 
  159 /* incoming traffic will be queued here */
  160 struct ifqueue ppoediscinq = { NULL };
  161 struct ifqueue ppoeinq = { NULL };
  162 
  163 extern int sppp_ioctl(struct ifnet *, unsigned long, void *);
  164 
  165 /* input routines */
  166 static void pppoe_disc_input(struct mbuf *);
  167 static void pppoe_dispatch_disc_pkt(struct mbuf *, int);
  168 static void pppoe_data_input(struct mbuf *);
  169 
  170 /* management routines */
  171 void pppoeattach(int);
  172 static int  pppoe_connect(struct pppoe_softc *);
  173 static int  pppoe_disconnect(struct pppoe_softc *);
  174 static void pppoe_abort_connect(struct pppoe_softc *);
  175 static int  pppoe_ioctl(struct ifnet *, unsigned long, caddr_t);
  176 static void pppoe_tls(struct sppp *);
  177 static void pppoe_tlf(struct sppp *);
  178 static void pppoe_start(struct ifnet *);
  179 
  180 /* internal timeout handling */
  181 static void pppoe_timeout(void *);
  182 
  183 /* sending actual protocol controll packets */
  184 static int pppoe_send_padi(struct pppoe_softc *);
  185 static int pppoe_send_padr(struct pppoe_softc *);
  186 #ifdef PPPOE_SERVER
  187 static int pppoe_send_pado(struct pppoe_softc *);
  188 static int pppoe_send_pads(struct pppoe_softc *);
  189 #endif
  190 static int pppoe_send_padt(struct ifnet *, u_int, const u_int8_t *);
  191 
  192 /* raw output */
  193 static int pppoe_output(struct pppoe_softc *, struct mbuf *);
  194 
  195 /* internal helper functions */
  196 static struct pppoe_softc *pppoe_find_softc_by_session(u_int, struct ifnet *);
  197 static struct pppoe_softc *pppoe_find_softc_by_hunique(u_int8_t *, size_t, struct ifnet *);
  198 static struct mbuf        *pppoe_get_mbuf(size_t len);
  199 
  200 LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list;
  201 
  202 /* interface cloning */
  203 int pppoe_clone_create(struct if_clone *, int);
  204 int pppoe_clone_destroy(struct ifnet *);
  205 
  206 struct if_clone pppoe_cloner =
  207     IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy);
  208 
  209 
  210 /* ARGSUSED */
  211 void
  212 pppoeattach(int count)
  213 {
  214         LIST_INIT(&pppoe_softc_list);
  215         if_clone_attach(&pppoe_cloner);
  216 
  217         ppoediscinq.ifq_maxlen = IFQ_MAXLEN;
  218         ppoeinq.ifq_maxlen = IFQ_MAXLEN;
  219 }
  220 
  221 /* Create a new interface. */
  222 int
  223 pppoe_clone_create(struct if_clone *ifc, int unit)
  224 {
  225         struct pppoe_softc *sc;
  226         int s;
  227 
  228         MALLOC(sc, struct pppoe_softc *, sizeof(*sc), M_DEVBUF, M_WAITOK);
  229         if (sc == NULL)
  230                 return (ENOMEM);
  231         bzero(sc, sizeof(struct pppoe_softc));
  232 
  233         sc->sc_unique = arc4random();
  234 
  235         snprintf(sc->sc_sppp.pp_if.if_xname, 
  236                  sizeof(sc->sc_sppp.pp_if.if_xname), 
  237                  "pppoe%d", unit);
  238         sc->sc_sppp.pp_if.if_softc = sc;
  239         sc->sc_sppp.pp_if.if_mtu = PPPOE_MAXMTU;
  240         sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST;
  241         sc->sc_sppp.pp_if.if_type = IFT_PPP;
  242         sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN;
  243         sc->sc_sppp.pp_flags |= PP_KEEPALIVE |          /* use LCP keepalive */
  244                                 PP_NOFRAMING;           /* no serial encapsulation */
  245         sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN;    /* framing added to ppp packets */
  246         sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl;
  247         sc->sc_sppp.pp_if.if_start = pppoe_start;
  248         sc->sc_sppp.pp_tls = pppoe_tls;
  249         sc->sc_sppp.pp_tlf = pppoe_tlf;
  250         IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN);
  251         IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd);
  252 
  253         /* changed to real address later */
  254         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
  255         
  256         /* init timer for interface watchdog */
  257         timeout_set(&sc->sc_timeout, pppoe_timeout, sc);
  258         
  259         if_attach(&sc->sc_sppp.pp_if);
  260         if_alloc_sadl(&sc->sc_sppp.pp_if);
  261         sppp_attach(&sc->sc_sppp.pp_if);
  262 #if NBPFILTER > 0
  263         bpfattach(&sc->sc_sppp.pp_if.if_bpf, &sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0);
  264 #endif
  265         
  266         s = splnet();
  267         LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list);
  268         splx(s);
  269 
  270         return (0);
  271 }
  272 
  273 /* Destroy a given interface. */
  274 int
  275 pppoe_clone_destroy(struct ifnet *ifp)
  276 {
  277         struct pppoe_softc *sc = ifp->if_softc;
  278         int s;
  279 
  280         s = splnet();
  281         LIST_REMOVE(sc, sc_list);
  282         timeout_del(&sc->sc_timeout);
  283         splx(s);
  284         
  285         sppp_detach(&sc->sc_sppp.pp_if);
  286         if_detach(ifp);
  287 
  288         if (sc->sc_concentrator_name)
  289                 free(sc->sc_concentrator_name, M_DEVBUF);
  290         if (sc->sc_service_name)
  291                 free(sc->sc_service_name, M_DEVBUF);
  292         if (sc->sc_ac_cookie)
  293                 free(sc->sc_ac_cookie, M_DEVBUF);
  294 
  295         free(sc, M_DEVBUF);
  296 
  297         return (0);
  298 }
  299 
  300 /*
  301  * Find the interface handling the specified session.
  302  * Note: O(number of sessions open), this is a client-side only, mean
  303  * and lean implementation, so number of open sessions typically should
  304  * be 1.
  305  */
  306 static struct pppoe_softc *
  307 pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif)
  308 {
  309         struct pppoe_softc *sc;
  310 
  311         if (session == 0)
  312                 return (NULL);
  313 
  314         LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
  315                 if (sc->sc_state == PPPOE_STATE_SESSION
  316                     && sc->sc_session == session) {
  317                         if (sc->sc_eth_if == rcvif)
  318                                 return (sc);
  319                         else
  320                                 return (NULL);
  321                 }
  322         }
  323         return (NULL);
  324 }
  325 
  326 /* 
  327  * Check host unique token passed and return appropriate softc pointer,
  328  * or NULL if token is bogus.
  329  */
  330 static struct pppoe_softc *
  331 pppoe_find_softc_by_hunique(u_int8_t *token, size_t len, struct ifnet *rcvif)
  332 {
  333         struct pppoe_softc *sc;
  334         u_int32_t hunique;
  335 
  336         if (LIST_EMPTY(&pppoe_softc_list))
  337                 return (NULL);
  338 
  339         if (len != sizeof(hunique))
  340                 return (NULL);
  341         memcpy(&hunique, token, len);
  342 
  343         LIST_FOREACH(sc, &pppoe_softc_list, sc_list)
  344                 if (sc->sc_unique == hunique)
  345                         break;
  346 
  347         if (sc == NULL) {
  348                 printf("pppoe: alien host unique tag, no session found\n");
  349                 return (NULL);
  350         }
  351 
  352         /* should be safe to access *sc now */
  353         if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) {
  354                 printf("%s: host unique tag found, but it belongs to a connection in state %d\n",
  355                         sc->sc_sppp.pp_if.if_xname, sc->sc_state);
  356                 return (NULL);
  357         }
  358         if (sc->sc_eth_if != rcvif) {
  359                 printf("%s: wrong interface, not accepting host unique\n",
  360                         sc->sc_sppp.pp_if.if_xname);
  361                 return (NULL);
  362         }
  363         return (sc);
  364 }
  365 
  366 /* Interface interrupt handler routine. */
  367 void
  368 pppoeintr(void)
  369 {
  370         struct pppoe_softc *sc;
  371         struct mbuf *m;
  372 
  373         splassert(IPL_SOFTNET);
  374         
  375         LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
  376                 while (ppoediscinq.ifq_head) {
  377                         MBUFLOCK(IF_DEQUEUE(&ppoediscinq, m););
  378                         if (m == NULL)
  379                                 break;
  380                         pppoe_disc_input(m);
  381                 }
  382 
  383                 while (ppoeinq.ifq_head) {
  384                         MBUFLOCK(IF_DEQUEUE(&ppoeinq, m););
  385                         if (m == NULL)
  386                                 break;
  387                         pppoe_data_input(m);
  388                 }
  389         }
  390 }
  391 
  392 /* Analyze and handle a single received packet while not in session state. */
  393 static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
  394 {
  395         struct pppoe_softc *sc;
  396         struct pppoehdr *ph;
  397         struct pppoetag *pt;
  398         struct mbuf *n;
  399         struct ether_header *eh;
  400         const char *err_msg, *devname;
  401         size_t ac_cookie_len;
  402         int noff, err, errortag;
  403         u_int16_t tag, len;
  404         u_int16_t session, plen;
  405         u_int8_t *ac_cookie;
  406 #ifdef PPPOE_SERVER
  407         u_int8_t *hunique;
  408         size_t hunique_len;
  409 #endif
  410 
  411         err_msg = NULL;
  412         devname = "pppoe";
  413         errortag = 0;
  414 
  415         if (m->m_len < sizeof(*eh)) {
  416                 m = m_pullup(m, sizeof(*eh));
  417                 if (m == NULL)
  418                         goto done;
  419         }
  420         eh = mtod(m, struct ether_header *);
  421         off += sizeof(*eh);
  422 
  423         ac_cookie = NULL;
  424         ac_cookie_len = 0;
  425 #ifdef PPPOE_SERVER
  426         hunique = NULL;
  427         hunique_len = 0;
  428 #endif
  429 
  430         session = 0;
  431         if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) {
  432                 printf("pppoe: packet too short: %d\n", m->m_pkthdr.len);
  433                 goto done;
  434         }
  435 
  436         n = m_pulldown(m, off, sizeof(*ph), &noff);
  437         if (n == NULL) {
  438                 printf("pppoe: could not get PPPoE header\n");
  439                 m = NULL;
  440                 goto done;
  441         }
  442         ph = (struct pppoehdr *)(mtod(n, caddr_t) + noff);
  443         if (ph->vertype != PPPOE_VERTYPE) {
  444                 printf("pppoe: unknown version/type packet: 0x%x\n",
  445                     ph->vertype);
  446                 goto done;
  447         }
  448 
  449         session = ntohs(ph->session);
  450         plen = ntohs(ph->plen);
  451         off += sizeof(*ph);
  452         if (plen + off > m->m_pkthdr.len) {
  453                 printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
  454                     m->m_pkthdr.len - off, plen);
  455                 goto done;
  456         }
  457 
  458         /* ignore trailing garbage */
  459         m_adj(m, off + plen - m->m_pkthdr.len);
  460 
  461         tag = 0;
  462         len = 0;
  463         sc = NULL;
  464         while (off + sizeof(*pt) <= m->m_pkthdr.len) {
  465                 n = m_pulldown(m, off, sizeof(*pt), &noff);
  466                 if (n == NULL) {
  467                         printf("%s: parse error\n", devname);
  468                         m = NULL;
  469                         goto done;
  470                 }
  471                 pt = (struct pppoetag *)(mtod(n, caddr_t) + noff);
  472                 tag = ntohs(pt->tag);
  473                 len = ntohs(pt->len);
  474                 if (off + len > m->m_pkthdr.len) {
  475                         printf("%s: tag 0x%x len 0x%x is too long\n",
  476                             devname, tag, len);
  477                         goto done;
  478                 }
  479                 switch (tag) {
  480                 case PPPOE_TAG_EOL:
  481                         goto breakbreak;
  482                 case PPPOE_TAG_SNAME:
  483                         break;  /* ignored */
  484                 case PPPOE_TAG_ACNAME:
  485                         break;  /* ignored */
  486                 case PPPOE_TAG_HUNIQUE:
  487                         if (sc != NULL)
  488                                 break;
  489                         n = m_pulldown(m, off + sizeof(*pt), len, &noff);
  490                         if (n == NULL) {
  491                                 m = NULL;
  492                                 err_msg = "TAG HUNIQUE ERROR";
  493                                 break;
  494                         }
  495 #ifdef PPPOE_SERVER
  496                         hunique = mtod(n, caddr_t) + noff;
  497                         hunique_len = len;
  498 #endif
  499                         sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t) + noff,
  500                             len, m->m_pkthdr.rcvif);
  501                         if (sc != NULL)
  502                                 devname = sc->sc_sppp.pp_if.if_xname;
  503                         break;
  504                 case PPPOE_TAG_ACCOOKIE:
  505                         if (ac_cookie == NULL) {
  506                                 n = m_pulldown(m, off + sizeof(*pt), len,
  507                                     &noff);
  508                                 if (n == NULL) {
  509                                         err_msg = "TAG ACCOOKIE ERROR";
  510                                         m = NULL;
  511                                         break;
  512                                 }
  513                                 ac_cookie = mtod(n, caddr_t) + noff;
  514                                 ac_cookie_len = len;
  515                         }
  516                         break;
  517                 case PPPOE_TAG_SNAME_ERR:
  518                         err_msg = "SERVICE NAME ERROR";
  519                         errortag = 1;
  520                         break;
  521                 case PPPOE_TAG_ACSYS_ERR:
  522                         err_msg = "AC SYSTEM ERROR";
  523                         errortag = 1;
  524                         break;
  525                 case PPPOE_TAG_GENERIC_ERR:
  526                         err_msg = "GENERIC ERROR";
  527                         errortag = 1;
  528                         break;
  529                 }
  530                 if (err_msg) {
  531                         log(LOG_INFO, "%s: %s: ", devname, err_msg);
  532                         if (errortag && len) {
  533                                 n = m_pulldown(m, off + sizeof(*pt), len,
  534                                     &noff);
  535                                 if (n) {
  536                                         u_int8_t *et = mtod(n, caddr_t) + noff;
  537                                         while (len--)
  538                                                 addlog("%c", *et++);
  539                                 }
  540                         }
  541                         addlog("\n");
  542                         goto done;
  543                 }
  544                 off += sizeof(*pt) + len;
  545         }
  546 breakbreak:
  547         switch (ph->code) {
  548         case PPPOE_CODE_PADI:
  549 #ifdef PPPOE_SERVER
  550                 /*
  551                  * Got service name, concentrator name, and/or host unique.
  552                  * Ignore if we have no interfaces with IFF_PASSIVE|IFF_UP.
  553                  */
  554                 if (LIST_EMPTY(&pppoe_softc_list))
  555                         goto done;
  556                 
  557                 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
  558                         if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP))
  559                                 continue;
  560                         if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE))
  561                                 continue;
  562                         if (sc->sc_state == PPPOE_STATE_INITIAL)
  563                                 break;
  564                 }
  565                 if (sc == NULL) {
  566 #ifdef PPPOE_DEBUG
  567                         printf("pppoe: free passive interface is not found\n");
  568 #endif
  569                         goto done;
  570                 }
  571                 if (hunique) {
  572                         if (sc->sc_hunique)
  573                                 free(sc->sc_hunique, M_DEVBUF);
  574                         sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
  575                             M_DONTWAIT);
  576                         if (sc->sc_hunique == NULL)
  577                                 goto done;
  578                         sc->sc_hunique_len = hunique_len;
  579                         memcpy(sc->sc_hunique, hunique, hunique_len);
  580                 }
  581                 
  582                 memcpy(&sc->sc_dest, eh->ether_shost, sizeof(sc->sc_dest));
  583                 sc->sc_state = PPPOE_STATE_PADO_SENT;
  584                 pppoe_send_pado(sc);
  585 
  586                 break;
  587 #endif /* PPPOE_SERVER */
  588         case PPPOE_CODE_PADR:
  589 #ifdef PPPOE_SERVER
  590                 /*
  591                  * Get sc from ac_cookie if IFF_PASSIVE.
  592                  */
  593                 if (ac_cookie == NULL) {
  594                         /* be quiet if there is not a single pppoe instance */
  595                         printf("pppoe: received PADR but not includes ac_cookie\n");
  596                         goto done;
  597                 }
  598                 
  599                 sc = pppoe_find_softc_by_hunique(ac_cookie,
  600                                                  ac_cookie_len,
  601                                                  m->m_pkthdr.rcvif);
  602                 if (sc == NULL) {
  603                         /* be quiet if there is not a single pppoe instance */
  604                         if (!LIST_EMPTY(&pppoe_softc_list))
  605                                 printf("pppoe: received PADR but could not find request for it\n");
  606                         goto done;
  607                 }
  608                 if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
  609                         printf("%s: received unexpected PADR\n",
  610                             sc->sc_sppp.pp_if.if_xname);
  611                         goto done;
  612                 }
  613                 if (hunique) {
  614                         if (sc->sc_hunique)
  615                                 free(sc->sc_hunique, M_DEVBUF);
  616                         sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
  617                             M_DONTWAIT);
  618                         if (sc->sc_hunique == NULL)
  619                                 goto done;
  620                         sc->sc_hunique_len = hunique_len;
  621                         memcpy(sc->sc_hunique, hunique, hunique_len);
  622                 }
  623                 
  624                 pppoe_send_pads(sc);
  625                 sc->sc_state = PPPOE_STATE_SESSION;
  626                 sc->sc_sppp.pp_up(&sc->sc_sppp);
  627                 
  628                 break;
  629 #else
  630                 /* ignore, we are no access concentrator */
  631                 goto done;
  632 #endif /* PPPOE_SERVER */
  633         case PPPOE_CODE_PADO:
  634                 if (sc == NULL) {
  635                         /* be quiet if there is not a single pppoe instance */
  636                         if (!LIST_EMPTY(&pppoe_softc_list))
  637                                 printf("pppoe: received PADO but could not find request for it\n");
  638                         goto done;
  639                 }
  640                 if (sc->sc_state != PPPOE_STATE_PADI_SENT) {
  641                         printf("%s: received unexpected PADO\n",
  642                             sc->sc_sppp.pp_if.if_xname);
  643                         goto done;
  644                 }
  645                 if (ac_cookie) {
  646                         if (sc->sc_ac_cookie)
  647                                 free(sc->sc_ac_cookie, M_DEVBUF);
  648                         sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF,
  649                             M_DONTWAIT);
  650                         if (sc->sc_ac_cookie == NULL)
  651                                 goto done;
  652                         sc->sc_ac_cookie_len = ac_cookie_len;
  653                         memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
  654                 }
  655                 
  656                 memcpy(&sc->sc_dest, eh->ether_shost, sizeof(sc->sc_dest));
  657                 timeout_del(&sc->sc_timeout);
  658                 sc->sc_padr_retried = 0;
  659                 sc->sc_state = PPPOE_STATE_PADR_SENT;
  660                 if ((err = pppoe_send_padr(sc)) != 0) {
  661                         PPPOEDEBUG(("%s: failed to send PADR, error=%d\n",
  662                             sc->sc_sppp.pp_if.if_xname, err));
  663                 }
  664                 timeout_add(&sc->sc_timeout,
  665                     PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried));
  666                 
  667                 break;
  668         case PPPOE_CODE_PADS:
  669                 if (sc == NULL)
  670                         goto done;
  671                 
  672                 sc->sc_session = session;
  673                 timeout_del(&sc->sc_timeout);
  674                 PPPOEDEBUG(("%s: session 0x%x connected\n",
  675                     sc->sc_sppp.pp_if.if_xname, session));
  676                 sc->sc_state = PPPOE_STATE_SESSION;
  677                 microtime(&sc->sc_session_time);
  678                 sc->sc_sppp.pp_up(&sc->sc_sppp);        /* notify upper layers */
  679                 
  680                 break;
  681         case PPPOE_CODE_PADT:
  682                 if (sc == NULL)
  683                         goto done;
  684                 
  685                 /* stop timer (we might be about to transmit a PADT ourself) */
  686                 timeout_del(&sc->sc_timeout);
  687                 PPPOEDEBUG(("%s: session 0x%x terminated, received PADT\n",
  688                     sc->sc_sppp.pp_if.if_xname, session));
  689                 
  690                 /* clean up softc */
  691                 sc->sc_state = PPPOE_STATE_INITIAL;
  692                 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
  693                 if (sc->sc_ac_cookie) {
  694                         free(sc->sc_ac_cookie, M_DEVBUF);
  695                         sc->sc_ac_cookie = NULL;
  696                 }
  697                 sc->sc_ac_cookie_len = 0;
  698                 sc->sc_session = 0;
  699                 sc->sc_session_time.tv_sec = 0;
  700                 sc->sc_session_time.tv_usec = 0;
  701                 sc->sc_sppp.pp_down(&sc->sc_sppp);      /* signal upper layer */ 
  702 
  703                 break;
  704         default:
  705                 printf("%s: unknown code (0x%04x) session = 0x%04x\n",
  706                     sc ? sc->sc_sppp.pp_if.if_xname : "pppoe",
  707                     ph->code, session);
  708                 break;
  709         }
  710 
  711 done:
  712         m_freem(m);
  713 }
  714 
  715 /* Input function for discovery packets. */
  716 static void
  717 pppoe_disc_input(struct mbuf *m)
  718 {
  719         /* avoid error messages if there is not a single pppoe instance */
  720         if (!LIST_EMPTY(&pppoe_softc_list)) {
  721                 KASSERT(m->m_flags & M_PKTHDR);
  722                 pppoe_dispatch_disc_pkt(m, 0);
  723         } else
  724                 m_freem(m);
  725 }
  726 
  727 /* Input function for data packets */
  728 static void
  729 pppoe_data_input(struct mbuf *m)
  730 {
  731         struct pppoe_softc *sc;
  732         struct pppoehdr *ph;
  733         u_int16_t session, plen;
  734 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
  735         u_int8_t shost[ETHER_ADDR_LEN];
  736 #endif
  737 
  738         KASSERT(m->m_flags & M_PKTHDR);
  739 
  740 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
  741         memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN);
  742 #endif
  743         m_adj(m, sizeof(struct ether_header));
  744         if (m->m_pkthdr.len <= PPPOE_HEADERLEN) {
  745                 printf("pppoe (data): dropping too short packet: %d bytes\n",
  746                     m->m_pkthdr.len);
  747                 goto drop;
  748         }
  749         if (m->m_len < sizeof(*ph)) {
  750                 m = m_pullup(m, sizeof(*ph));
  751                 if (m == NULL) {
  752                         printf("pppoe (data): could not get PPPoE header\n");
  753                         return;
  754                 }
  755         }
  756         ph = mtod(m, struct pppoehdr *);
  757         if (ph->vertype != PPPOE_VERTYPE) {
  758                 printf("pppoe (data): unknown version/type packet: 0x%x\n",
  759                     ph->vertype);
  760                 goto drop;
  761         }
  762         if (ph->code != 0)
  763                 goto drop;
  764 
  765         session = ntohs(ph->session);
  766         sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif);
  767         if (sc == NULL) {
  768 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
  769                 printf("pppoe (data): input for unknown session 0x%x, sending PADT\n",
  770                     session);
  771                 pppoe_send_padt(m->m_pkthdr.rcvif, session, shost);
  772 #endif
  773                 goto drop;
  774         }
  775 
  776         plen = ntohs(ph->plen);
  777 
  778 #if NBPFILTER > 0
  779         if(sc->sc_sppp.pp_if.if_bpf)
  780                 bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m, BPF_DIRECTION_IN);
  781 #endif
  782 
  783         m_adj(m, PPPOE_HEADERLEN);
  784 
  785 #ifdef PPPOE_DEBUG
  786         {
  787                 struct mbuf *p;
  788 
  789                 printf("%s: pkthdr.len=%d, pppoe.len=%d",
  790                         sc->sc_sppp.pp_if.if_xname,
  791                         m->m_pkthdr.len, plen);
  792                 p = m;
  793                 while (p) {
  794                         printf(" l=%d", p->m_len);
  795                         p = p->m_next;
  796                 }
  797                 printf("\n");
  798         }
  799 #endif
  800 
  801         if (m->m_pkthdr.len < plen)
  802                 goto drop;
  803 
  804         /* fix incoming interface pointer (not the raw ethernet interface anymore) */
  805         m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if;
  806 
  807         /* pass packet up and account for it */
  808         sc->sc_sppp.pp_if.if_ipackets++;
  809         sppp_input(&sc->sc_sppp.pp_if, m);
  810         return;
  811 
  812 drop:
  813         m_freem(m);
  814 }
  815 
  816 static int
  817 pppoe_output(struct pppoe_softc *sc, struct mbuf *m)
  818 {
  819         struct sockaddr dst;
  820         struct ether_header *eh;
  821         u_int16_t etype;
  822 
  823         if (sc->sc_eth_if == NULL) {
  824                 m_freem(m);
  825                 return (EIO);
  826         }
  827         
  828         if ((sc->sc_eth_if->if_flags & (IFF_UP|IFF_RUNNING))
  829             != (IFF_UP|IFF_RUNNING)) {
  830                 m_freem(m);
  831                 return (ENETDOWN);
  832         }
  833 
  834         memset(&dst, 0, sizeof dst);
  835         dst.sa_family = AF_UNSPEC;
  836         eh = (struct ether_header*)&dst.sa_data;
  837         etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC;
  838         eh->ether_type = htons(etype);
  839         memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest);
  840 
  841         PPPOEDEBUG(("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n",
  842             sc->sc_sppp.pp_if.if_xname, etype,
  843             sc->sc_state, sc->sc_session,
  844             ether_sprintf((unsigned char *)&sc->sc_dest), m->m_pkthdr.len));
  845 
  846         m->m_flags &= ~(M_BCAST|M_MCAST);
  847         sc->sc_sppp.pp_if.if_opackets++;
  848         return (sc->sc_eth_if->if_output(sc->sc_eth_if, m, &dst, NULL));
  849 }
  850 
  851 /* The ioctl routine. */
  852 static int
  853 pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
  854 {
  855         struct proc *p = curproc;       /* XXX */
  856         struct pppoe_softc *sc = (struct pppoe_softc *)ifp;
  857         int error = 0;
  858 
  859         switch (cmd) {
  860         case PPPOESETPARMS:
  861         {
  862                 struct pppoediscparms *parms = (struct pppoediscparms *)data;
  863                 int len;
  864                 
  865                 if ((error = suser(p, p->p_acflag)) != 0)
  866                         return (error);
  867                 if (parms->eth_ifname[0] != '\0') {
  868                         sc->sc_eth_if = ifunit(parms->eth_ifname);
  869                         if (sc->sc_eth_if == NULL)
  870                                 return (ENXIO);
  871                 }
  872 
  873                 if (sc->sc_concentrator_name)
  874                         free(sc->sc_concentrator_name, M_DEVBUF);
  875                 sc->sc_concentrator_name = NULL;
  876 
  877                 len = strlen(parms->ac_name);
  878                 if (len > 0 && len < sizeof(parms->ac_name)) {
  879                         char *p = malloc(len + 1, M_DEVBUF, M_WAITOK);
  880                         if (p == NULL)
  881                                 return (ENOMEM);
  882                         strlcpy(p, parms->ac_name, len + 1);
  883                         sc->sc_concentrator_name = p;
  884                 }
  885 
  886                 if (sc->sc_service_name)
  887                         free(sc->sc_service_name, M_DEVBUF);
  888                 sc->sc_service_name = NULL;
  889 
  890                 len = strlen(parms->service_name);
  891                 if (len > 0 && len < sizeof(parms->service_name)) {
  892                         char *p = malloc(len + 1, M_DEVBUF, M_WAITOK);
  893                         if (p == NULL)
  894                                 return (ENOMEM);
  895                         strlcpy(p, parms->service_name, len + 1);
  896                         sc->sc_service_name = p;
  897                 }
  898                 return (0);
  899         }
  900         break;
  901         case PPPOEGETPARMS:
  902         {
  903                 struct pppoediscparms *parms = (struct pppoediscparms *)data;
  904 
  905                 if (sc->sc_eth_if)
  906                         strlcpy(parms->eth_ifname, sc->sc_eth_if->if_xname,
  907                             IFNAMSIZ);
  908                 else
  909                         parms->eth_ifname[0] = '\0';
  910 
  911                 if (sc->sc_concentrator_name)
  912                         strlcpy(parms->ac_name, sc->sc_concentrator_name,
  913                             sizeof(parms->ac_name));
  914                 else
  915                         parms->ac_name[0] = '\0';
  916 
  917                 if (sc->sc_service_name)
  918                         strlcpy(parms->service_name, sc->sc_service_name,
  919                             sizeof(parms->service_name));
  920                 else
  921                         parms->service_name[0] = '\0';
  922 
  923                 return (0);
  924         }
  925         break;
  926         case PPPOEGETSESSION:
  927         {
  928                 struct pppoeconnectionstate *state =
  929                     (struct pppoeconnectionstate *)data;
  930                 state->state = sc->sc_state;
  931                 state->session_id = sc->sc_session;
  932                 state->padi_retry_no = sc->sc_padi_retried;
  933                 state->padr_retry_no = sc->sc_padr_retried;
  934                 state->session_time.tv_sec = sc->sc_session_time.tv_sec;
  935                 state->session_time.tv_usec = sc->sc_session_time.tv_usec;
  936                 return (0);
  937         }
  938         break;
  939         case SIOCSIFFLAGS:
  940         {
  941                 struct ifreq *ifr = (struct ifreq *)data;
  942                 /*
  943                  * Prevent running re-establishment timers overriding
  944                  * administrators choice.
  945                  */
  946                 if ((ifr->ifr_flags & IFF_UP) == 0
  947                      && sc->sc_state >= PPPOE_STATE_PADI_SENT
  948                      && sc->sc_state < PPPOE_STATE_SESSION) {
  949                         timeout_del(&sc->sc_timeout);
  950                         sc->sc_state = PPPOE_STATE_INITIAL;
  951                         sc->sc_padi_retried = 0;
  952                         sc->sc_padr_retried = 0;
  953                         memcpy(&sc->sc_dest, etherbroadcastaddr,
  954                             sizeof(sc->sc_dest));
  955                 }
  956                 return (sppp_ioctl(ifp, cmd, data));
  957         }
  958         case SIOCSIFMTU:
  959         {
  960                 struct ifreq *ifr = (struct ifreq *)data;
  961 
  962                 if (ifr->ifr_mtu > PPPOE_MAXMTU)
  963                         return (EINVAL);
  964                 return (sppp_ioctl(ifp, cmd, data));
  965         }
  966         default:
  967                 return (sppp_ioctl(ifp, cmd, data));
  968         }
  969         return (0);
  970 }
  971 
  972 /*
  973  * Allocate a mbuf/cluster with space to store the given data length
  974  * of payload, leaving space for prepending an ethernet header
  975  * in front. 
  976  */
  977 static struct mbuf *
  978 pppoe_get_mbuf(size_t len)
  979 {
  980         struct mbuf *m;
  981 
  982         MGETHDR(m, M_DONTWAIT, MT_DATA);
  983         if (m == NULL)
  984                 return (NULL);
  985         if (len + sizeof(struct ether_header) > MHLEN) {
  986                 MCLGET(m, M_DONTWAIT);
  987                 if ((m->m_flags & M_EXT) == 0) {
  988                         struct mbuf *n;
  989 
  990                         MFREE(m, n);
  991                         return (NULL);
  992                 }
  993         }
  994         m->m_data += sizeof(struct ether_header);
  995         m->m_len = len;
  996         m->m_pkthdr.len = len;
  997         m->m_pkthdr.rcvif = NULL;
  998 
  999         return (m);
 1000 }
 1001 
 1002 /* Send PADI. */
 1003 static int
 1004 pppoe_send_padi(struct pppoe_softc *sc)
 1005 {
 1006         struct mbuf *m0;
 1007         int len, l1 = 0, l2 = 0; /* XXX: gcc */
 1008         u_int8_t *p;
 1009 
 1010         if (sc->sc_state > PPPOE_STATE_PADI_SENT)
 1011                 panic("pppoe_send_padi in state %d", sc->sc_state);
 1012 
 1013         /* calculate length of frame (excluding ethernet header + pppoe header) */
 1014         len = 2 + 2 + 2 + 2 + sizeof(sc->sc_unique); /* service name tag is required, host unique is send too */
 1015         if (sc->sc_service_name != NULL) {
 1016                 l1 = strlen(sc->sc_service_name);
 1017                 len += l1;
 1018         }
 1019         if (sc->sc_concentrator_name != NULL) {
 1020                 l2 = strlen(sc->sc_concentrator_name);
 1021                 len += 2 + 2 + l2;
 1022         }
 1023 
 1024         /* allocate a buffer */
 1025         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);     /* header len + payload len */
 1026         if (m0 == NULL)
 1027                 return (ENOBUFS);
 1028 
 1029         /* fill in pkt */
 1030         p = mtod(m0, u_int8_t *);
 1031         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len);
 1032         PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
 1033         if (sc->sc_service_name != NULL) {
 1034                 PPPOE_ADD_16(p, l1);
 1035                 memcpy(p, sc->sc_service_name, l1);
 1036                 p += l1;
 1037         } else {
 1038                 PPPOE_ADD_16(p, 0);
 1039         }
 1040         if (sc->sc_concentrator_name != NULL) {
 1041                 PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
 1042                 PPPOE_ADD_16(p, l2);
 1043                 memcpy(p, sc->sc_concentrator_name, l2);
 1044                 p += l2;
 1045         }
 1046         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1047         PPPOE_ADD_16(p, sizeof(sc->sc_unique));
 1048         memcpy(p, &sc->sc_unique, sizeof(sc->sc_unique));
 1049 
 1050 #ifdef PPPOE_DEBUG
 1051         p += sizeof(sc->sc_unique);
 1052         if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN)
 1053                 panic("pppoe_send_padi: garbled output len, should be %ld, is %ld",
 1054                     (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *)));
 1055 #endif
 1056 
 1057         /* send pkt */
 1058         return (pppoe_output(sc, m0));
 1059 }
 1060 
 1061 /* Watchdog function. */
 1062 static void
 1063 pppoe_timeout(void *arg)
 1064 {
 1065         struct pppoe_softc *sc = (struct pppoe_softc *)arg;
 1066         int x, retry_wait, err;
 1067 
 1068         PPPOEDEBUG(("%s: timeout\n", sc->sc_sppp.pp_if.if_xname));
 1069 
 1070         switch (sc->sc_state) {
 1071         case PPPOE_STATE_PADI_SENT:
 1072                 /*
 1073                  * We have two basic ways of retrying:
 1074                  *  - Quick retry mode: try a few times in short sequence
 1075                  *  - Slow retry mode: we already had a connection successfully
 1076                  *    established and will try infinitely (without user
 1077                  *    intervention)
 1078                  * We only enter slow retry mode if IFF_LINK1 (aka autodial)
 1079                  * is not set.
 1080                  */
 1081 
 1082                 /* initialize for quick retry mode */
 1083                 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried);
 1084 
 1085                 x = splnet();
 1086                 sc->sc_padi_retried++;
 1087                 if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) {
 1088                         if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) {
 1089                                 /* slow retry mode */
 1090                                 retry_wait = PPPOE_SLOW_RETRY;
 1091                         } else {
 1092                                 pppoe_abort_connect(sc);
 1093                                 splx(x);
 1094                                 return;
 1095                         }
 1096                 }
 1097                 if ((err = pppoe_send_padi(sc)) != 0) {
 1098                         sc->sc_padi_retried--;
 1099                         PPPOEDEBUG(("%s: failed to transmit PADI, error=%d\n",
 1100                             sc->sc_sppp.pp_if.if_xname, err));
 1101                 }
 1102                 timeout_add(&sc->sc_timeout, retry_wait);
 1103                 splx(x);
 1104                 
 1105                 break;
 1106         case PPPOE_STATE_PADR_SENT:
 1107                 x = splnet();
 1108                 sc->sc_padr_retried++;
 1109                 if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) {
 1110                         memcpy(&sc->sc_dest, etherbroadcastaddr,
 1111                             sizeof(sc->sc_dest));
 1112                         sc->sc_state = PPPOE_STATE_PADI_SENT;
 1113                         sc->sc_padr_retried = 0;
 1114                         if ((err = pppoe_send_padi(sc)) != 0) {
 1115                                 PPPOEDEBUG(("%s: failed to send PADI, error=%d\n",
 1116                                     sc->sc_sppp.pp_if.if_xname, err));
 1117                         }
 1118                         timeout_add(&sc->sc_timeout,
 1119                             PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried));
 1120                         splx(x);
 1121                         return;
 1122                 }
 1123                 if ((err = pppoe_send_padr(sc)) != 0) {
 1124                         sc->sc_padr_retried--;
 1125                         PPPOEDEBUG(("%s: failed to send PADR, error=%d\n",
 1126                             sc->sc_sppp.pp_if.if_xname, err));
 1127                 }
 1128                 timeout_add(&sc->sc_timeout,
 1129                     PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried));
 1130                 splx(x);
 1131         
 1132                 break;
 1133         case PPPOE_STATE_CLOSING:
 1134                 pppoe_disconnect(sc);
 1135                 break;
 1136         default:
 1137                 return; /* all done, work in peace */
 1138         }
 1139 }
 1140 
 1141 /* Start a connection (i.e. initiate discovery phase). */
 1142 static int
 1143 pppoe_connect(struct pppoe_softc *sc)
 1144 {
 1145         int x, err;
 1146 
 1147         if (sc->sc_state != PPPOE_STATE_INITIAL)
 1148                 return (EBUSY);
 1149 
 1150 #ifdef PPPOE_SERVER
 1151         /* wait for PADI if IFF_PASSIVE */
 1152         if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE))
 1153                 return (0);
 1154 #endif
 1155         x = splnet();
 1156         
 1157         /* save state, in case we fail to send PADI */
 1158         sc->sc_state = PPPOE_STATE_PADI_SENT;
 1159         sc->sc_padr_retried = 0;
 1160         err = pppoe_send_padi(sc);
 1161         if (err != 0)
 1162                 PPPOEDEBUG(("%s: failed to send PADI, error=%d\n",
 1163                     sc->sc_sppp.pp_if.if_xname, err));
 1164         
 1165         timeout_add(&sc->sc_timeout, PPPOE_DISC_TIMEOUT);
 1166         splx(x);
 1167         
 1168         return (err);
 1169 }
 1170 
 1171 /* disconnect */
 1172 static int
 1173 pppoe_disconnect(struct pppoe_softc *sc)
 1174 {
 1175         int err, x;
 1176 
 1177         x = splnet();
 1178 
 1179         if (sc->sc_state < PPPOE_STATE_SESSION)
 1180                 err = EBUSY;
 1181         else {
 1182                 PPPOEDEBUG(("%s: disconnecting\n",
 1183                     sc->sc_sppp.pp_if.if_xname));
 1184                 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const u_int8_t *)&sc->sc_dest);
 1185         }
 1186 
 1187         /* cleanup softc */
 1188         sc->sc_state = PPPOE_STATE_INITIAL;
 1189         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
 1190         if (sc->sc_ac_cookie) {
 1191                 free(sc->sc_ac_cookie, M_DEVBUF);
 1192                 sc->sc_ac_cookie = NULL;
 1193         }
 1194         sc->sc_ac_cookie_len = 0;
 1195 #ifdef PPPOE_SERVER
 1196         if (sc->sc_hunique) {
 1197                 free(sc->sc_hunique, M_DEVBUF);
 1198                 sc->sc_hunique = NULL;
 1199         }
 1200         sc->sc_hunique_len = 0;
 1201 #endif
 1202         sc->sc_session = 0;
 1203 
 1204         /* notify upper layer */
 1205         sc->sc_sppp.pp_down(&sc->sc_sppp);
 1206 
 1207         splx(x);
 1208 
 1209         return (err);
 1210 }
 1211 
 1212 /* Connection attempt aborted. */
 1213 static void
 1214 pppoe_abort_connect(struct pppoe_softc *sc)
 1215 {
 1216         printf("%s: could not establish connection\n",
 1217                 sc->sc_sppp.pp_if.if_xname);
 1218         sc->sc_state = PPPOE_STATE_CLOSING;
 1219 
 1220         /* notify upper layer */
 1221         sc->sc_sppp.pp_down(&sc->sc_sppp);
 1222 
 1223         /* clear connection state */
 1224         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
 1225         sc->sc_state = PPPOE_STATE_INITIAL;
 1226 }
 1227 
 1228 /* Send a PADR packet */
 1229 static int
 1230 pppoe_send_padr(struct pppoe_softc *sc)
 1231 {
 1232         struct mbuf *m0;
 1233         u_int8_t *p;
 1234         size_t len, l1 = 0; /* XXX: gcc */
 1235 
 1236         if (sc->sc_state != PPPOE_STATE_PADR_SENT)
 1237                 return (EIO);
 1238 
 1239         len = 2 + 2 + 2 + 2 + sizeof(sc->sc_unique);    /* service name, host unique */
 1240         if (sc->sc_service_name != NULL) {              /* service name tag maybe empty */
 1241                 l1 = strlen(sc->sc_service_name);
 1242                 len += l1;
 1243         }
 1244         if (sc->sc_ac_cookie_len > 0)
 1245                 len += 2 + 2 + sc->sc_ac_cookie_len;    /* AC cookie */
 1246 
 1247         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1248         if (m0 == NULL)
 1249                 return (ENOBUFS);
 1250 
 1251         p = mtod(m0, u_int8_t *);
 1252         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
 1253         PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
 1254 
 1255         if (sc->sc_service_name != NULL) {
 1256                 PPPOE_ADD_16(p, l1);
 1257                 memcpy(p, sc->sc_service_name, l1);
 1258                 p += l1;
 1259         } else {
 1260                 PPPOE_ADD_16(p, 0);
 1261         }
 1262         if (sc->sc_ac_cookie_len > 0) {
 1263                 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
 1264                 PPPOE_ADD_16(p, sc->sc_ac_cookie_len);
 1265                 memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
 1266                 p += sc->sc_ac_cookie_len;
 1267         }
 1268         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1269         PPPOE_ADD_16(p, sizeof(sc->sc_unique));
 1270         memcpy(p, &sc->sc_unique, sizeof(sc->sc_unique));
 1271 
 1272 #ifdef PPPOE_DEBUG
 1273         p += sizeof(sc->sc_unique);
 1274         if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN)
 1275                 panic("pppoe_send_padr: garbled output len, should be %ld, is %ld",
 1276                         (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *)));
 1277 #endif
 1278 
 1279         return (pppoe_output(sc, m0));
 1280 }
 1281 
 1282 /* Send a PADT packet. */
 1283 static int
 1284 pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const u_int8_t *dest)
 1285 {
 1286         struct ether_header *eh;
 1287         struct sockaddr dst;
 1288         struct mbuf *m0;
 1289         u_int8_t *p;
 1290 
 1291         m0 = pppoe_get_mbuf(PPPOE_HEADERLEN);
 1292         if (m0 == NULL)
 1293                 return (ENOBUFS);
 1294 
 1295         p = mtod(m0, u_int8_t *);
 1296         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0);
 1297 
 1298         memset(&dst, 0, sizeof(dst));
 1299         dst.sa_family = AF_UNSPEC;
 1300         eh = (struct ether_header *)&dst.sa_data;
 1301         eh->ether_type = htons(ETHERTYPE_PPPOEDISC);
 1302         memcpy(&eh->ether_dhost, dest, ETHER_ADDR_LEN);
 1303 
 1304         m0->m_flags &= ~(M_BCAST|M_MCAST);
 1305         return (outgoing_if->if_output(outgoing_if, m0, &dst, NULL));
 1306 }
 1307 
 1308 #ifdef PPPOE_SERVER
 1309 /* Send a PADO packet. */
 1310 static int
 1311 pppoe_send_pado(struct pppoe_softc *sc)
 1312 {
 1313         struct mbuf *m0;
 1314         size_t len;
 1315         u_int8_t *p;
 1316         
 1317         if (sc->sc_state != PPPOE_STATE_PADO_SENT)
 1318                 return (EIO);
 1319 
 1320         /* calc length */
 1321         len = 0;
 1322         /* include ac_cookie */
 1323         len += 2 + 2 + sizeof(sc->sc_unique);
 1324         /* include hunique */
 1325         len += 2 + 2 + sc->sc_hunique_len;
 1326         
 1327         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1328         if (m0 == NULL)
 1329                 return (ENOBUFS);
 1330 
 1331         p = mtod(m0, u_int8_t *);
 1332         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
 1333         PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
 1334         PPPOE_ADD_16(p, sizeof(sc->sc_unique));
 1335         memcpy(p, &sc, sizeof(sc->sc_unique));
 1336         p += sizeof(sc->sc_unique);
 1337         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1338         PPPOE_ADD_16(p, sc->sc_hunique_len);
 1339         memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
 1340 
 1341         return (pppoe_output(sc, m0));
 1342 }
 1343 
 1344 /* Send a PADS packet. */
 1345 static int
 1346 pppoe_send_pads(struct pppoe_softc *sc)
 1347 {
 1348         struct mbuf *m0;
 1349         size_t len, l1;
 1350         u_int8_t *p;
 1351 
 1352         if (sc->sc_state != PPPOE_STATE_PADO_SENT)
 1353                 return (EIO);
 1354 
 1355         sc->sc_session = mono_time.tv_sec % 0xff + 1;
 1356 
 1357         /* calc length */
 1358         len = 0;
 1359         /* include hunique */
 1360         len += 2 + 2 + 2 + 2 + sc->sc_hunique_len;      /* service name, host unique */
 1361         if (sc->sc_service_name != NULL) {              /* service name tag maybe empty */
 1362                 l1 = strlen(sc->sc_service_name);
 1363                 len += l1;
 1364         }
 1365         
 1366         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1367         if (m0 == NULL)
 1368                 return (ENOBUFS);
 1369 
 1370         p = mtod(m0, u_int8_t *);
 1371         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len);
 1372         PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
 1373         if (sc->sc_service_name != NULL) {
 1374                 PPPOE_ADD_16(p, l1);
 1375                 memcpy(p, sc->sc_service_name, l1);
 1376                 p += l1;
 1377         } else {
 1378                 PPPOE_ADD_16(p, 0);
 1379         }
 1380         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1381         PPPOE_ADD_16(p, sc->sc_hunique_len);
 1382         memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
 1383 
 1384         return (pppoe_output(sc, m0));
 1385 }
 1386 #endif
 1387 
 1388 /* this-layer-start function */
 1389 static void
 1390 pppoe_tls(struct sppp *sp)
 1391 {
 1392         struct pppoe_softc *sc = (void *)sp;
 1393         
 1394         if (sc->sc_state != PPPOE_STATE_INITIAL)
 1395                 return;
 1396         pppoe_connect(sc);
 1397 }
 1398 
 1399 /* this-layer-finish function */
 1400 static void
 1401 pppoe_tlf(struct sppp *sp)
 1402 {
 1403         struct pppoe_softc *sc = (void *)sp;
 1404         
 1405         if (sc->sc_state < PPPOE_STATE_SESSION)
 1406                 return;
 1407         /*
 1408          * Do not call pppoe_disconnect here, the upper layer state
 1409          * machine gets confused by this. We must return from this
 1410          * function and defer disconnecting to the timeout handler.
 1411          */
 1412         sc->sc_state = PPPOE_STATE_CLOSING;
 1413         timeout_add(&sc->sc_timeout, hz / 50);
 1414 }
 1415 
 1416 static void
 1417 pppoe_start(struct ifnet *ifp)
 1418 {
 1419         struct pppoe_softc *sc = (void *)ifp;
 1420         struct mbuf *m;
 1421         size_t len;
 1422         u_int8_t *p;
 1423 
 1424         if (sppp_isempty(ifp))
 1425                 return;
 1426 
 1427         /* are we ready to process data yet? */
 1428         if (sc->sc_state < PPPOE_STATE_SESSION) {
 1429                 sppp_flush(&sc->sc_sppp.pp_if);
 1430                 return;
 1431         }
 1432 
 1433         while ((m = sppp_dequeue(ifp)) != NULL) {
 1434                 len = m->m_pkthdr.len;
 1435                 M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
 1436                 if (m == NULL) {
 1437                         ifp->if_oerrors++;
 1438                         continue;
 1439                 }
 1440                 p = mtod(m, u_int8_t *);
 1441                 PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
 1442 
 1443 #if NBPFILTER > 0
 1444                 if(sc->sc_sppp.pp_if.if_bpf)
 1445                         bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m,
 1446                             BPF_DIRECTION_OUT);
 1447 #endif
 1448 
 1449                 pppoe_output(sc, m);
 1450         }
 1451 }

/* [<][>][^][v][top][bottom][index][help] */