The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/if_pppoe.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e347ccb05f713d331e61f77706de0c21


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.