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