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

Cache object: 4172b6dd120dde7f417f0a640f4092ea


[ 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.