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