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

Cache object: c6735f2304c92126188881176305a232


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