Bug Summary

File:net/if_pppoe.c
Warning:line 1299, column 3
Null pointer passed as 2nd argument to memory copy function

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name if_pppoe.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/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 NBPFILTER1 > 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 & 0x4) ? printf a : 0) ((sc->sc_sppp.pp_if.if_flags & IFF_DEBUG0x4) ? printf a : 0)
61
62struct pppoehdr {
63 u_int8_t vertype;
64 u_int8_t code;
65 u_int16_t session;
66 u_int16_t plen;
67} __packed__attribute__((__packed__));
68
69struct pppoetag {
70 u_int16_t tag;
71 u_int16_t len;
72} __packed__attribute__((__packed__));
73
74#define PPPOE_HEADERLENsizeof(struct pppoehdr) sizeof(struct pppoehdr)
75#define PPPOE_OVERHEAD(sizeof(struct pppoehdr) + 2) (PPPOE_HEADERLENsizeof(struct pppoehdr) + 2)
76#define PPPOE_VERTYPE0x11 0x11 /* VER=1, TYPE = 1 */
77
78#define PPPOE_TAG_EOL0x0000 0x0000 /* end of list */
79#define PPPOE_TAG_SNAME0x0101 0x0101 /* service name */
80#define PPPOE_TAG_ACNAME0x0102 0x0102 /* access concentrator name */
81#define PPPOE_TAG_HUNIQUE0x0103 0x0103 /* host unique */
82#define PPPOE_TAG_ACCOOKIE0x0104 0x0104 /* AC cookie */
83#define PPPOE_TAG_VENDOR0x0105 0x0105 /* vendor specific */
84#define PPPOE_TAG_RELAYSID0x0110 0x0110 /* relay session id */
85#define PPPOE_TAG_MAX_PAYLOAD0x0120 0x0120 /* RFC 4638 max payload */
86#define PPPOE_TAG_SNAME_ERR0x0201 0x0201 /* service name error */
87#define PPPOE_TAG_ACSYS_ERR0x0202 0x0202 /* AC system error */
88#define PPPOE_TAG_GENERIC_ERR0x0203 0x0203 /* generic error */
89
90#define PPPOE_CODE_PADI0x09 0x09 /* Active Discovery Initiation */
91#define PPPOE_CODE_PADO0x07 0x07 /* Active Discovery Offer */
92#define PPPOE_CODE_PADR0x19 0x19 /* Active Discovery Request */
93#define PPPOE_CODE_PADS0x65 0x65 /* Active Discovery Session confirmation */
94#define PPPOE_CODE_PADT0xA7 0xA7 /* Active Discovery Terminate */
95
96/* two byte PPP protocol discriminator, then IP data */
97#define PPPOE_MTU((1518 - ((6 * 2) + 2) - 4) - (sizeof(struct pppoehdr) + 2)) (ETHERMTU(1518 - ((6 * 2) + 2) - 4) - PPPOE_OVERHEAD(sizeof(struct pppoehdr) + 2))
98#define PPPOE_MAXMTU2048 PP_MAX_MRU2048
99
100/* Add a 16 bit unsigned value to a buffer pointed to by PTR */
101#define PPPOE_ADD_16(PTR, VAL)*(PTR)++ = (VAL) / 256; *(PTR)++ = (VAL) % 256 \
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)*(PTR)++ = 0x11; *(PTR)++ = (CODE); *(PTR)++ = (SESS) / 256; *
(PTR)++ = (SESS) % 256; *(PTR)++ = (LEN) / 256; *(PTR)++ = (LEN
) % 256
\
107 *(PTR)++ = PPPOE_VERTYPE0x11; \
108 *(PTR)++ = (CODE); \
109 PPPOE_ADD_16(PTR, SESS)*(PTR)++ = (SESS) / 256; *(PTR)++ = (SESS) % 256; \
110 PPPOE_ADD_16(PTR, LEN)*(PTR)++ = (LEN) / 256; *(PTR)++ = (LEN) % 256
111
112#define PPPOE_DISC_TIMEOUT5 5 /* base for quick timeout calculation (seconds) */
113#define PPPOE_SLOW_RETRY60 60 /* persistent retry interval (seconds) */
114#define PPPOE_DISC_MAXPADI4 4 /* retry PADI four times (quickly) */
115#define PPPOE_DISC_MAXPADR2 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
123struct pppoe_softc {
124 struct sppp sc_sppp; /* contains a struct ifnet as first element */
125 LIST_ENTRY(pppoe_softc)struct { struct pppoe_softc *le_next; struct pppoe_softc **le_prev
; }
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 */
147void pppoe_disc_input(struct mbuf *);
148void pppoe_data_input(struct mbuf *);
149static void pppoe_dispatch_disc_pkt(struct mbuf *);
150
151/* management routines */
152void pppoeattach(int);
153static int pppoe_connect(struct pppoe_softc *);
154static int pppoe_disconnect(struct pppoe_softc *);
155static void pppoe_abort_connect(struct pppoe_softc *);
156static int pppoe_ioctl(struct ifnet *, unsigned long, caddr_t);
157static void pppoe_tls(struct sppp *);
158static void pppoe_tlf(struct sppp *);
159static void pppoe_start(struct ifnet *);
160
161/* internal timeout handling */
162static void pppoe_timeout(void *);
163
164/* sending actual protocol control packets */
165static int pppoe_send_padi(struct pppoe_softc *);
166static int pppoe_send_padr(struct pppoe_softc *);
167static int pppoe_send_padt(unsigned int, u_int, const u_int8_t *, u_int8_t);
168
169/* raw output */
170static int pppoe_output(struct pppoe_softc *, struct mbuf *);
171
172/* internal helper functions */
173static struct pppoe_softc *pppoe_find_softc_by_session(u_int, u_int);
174static struct pppoe_softc *pppoe_find_softc_by_hunique(u_int8_t *, size_t, u_int);
175static struct mbuf *pppoe_get_mbuf(size_t len);
176
177LIST_HEAD(pppoe_softc_head, pppoe_softc)struct pppoe_softc_head { struct pppoe_softc *lh_first; } pppoe_softc_list;
178
179/* interface cloning */
180int pppoe_clone_create(struct if_clone *, int);
181int pppoe_clone_destroy(struct ifnet *);
182
183struct if_clone pppoe_cloner =
184 IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy){ .ifc_list = { ((void *)0), ((void *)0) }, .ifc_name = "pppoe"
, .ifc_namelen = sizeof("pppoe") - 1, .ifc_create = pppoe_clone_create
, .ifc_destroy = pppoe_clone_destroy, }
;
185
186struct mbuf_queue pppoediscinq = MBUF_QUEUE_INITIALIZER({ { ((void *)0), ((((0x2)) > 0x0 && ((0x2)) < 0x9
) ? 0x9 : ((0x2))), 0x0 }, { ((void *)0), ((void *)0), 0 }, (
256), 0 }
187 IFQ_MAXLEN, IPL_SOFTNET){ { ((void *)0), ((((0x2)) > 0x0 && ((0x2)) < 0x9
) ? 0x9 : ((0x2))), 0x0 }, { ((void *)0), ((void *)0), 0 }, (
256), 0 }
;
188struct mbuf_queue pppoeinq = MBUF_QUEUE_INITIALIZER({ { ((void *)0), ((((0x2)) > 0x0 && ((0x2)) < 0x9
) ? 0x9 : ((0x2))), 0x0 }, { ((void *)0), ((void *)0), 0 }, (
256), 0 }
189 IFQ_MAXLEN, IPL_SOFTNET){ { ((void *)0), ((((0x2)) > 0x0 && ((0x2)) < 0x9
) ? 0x9 : ((0x2))), 0x0 }, { ((void *)0), ((void *)0), 0 }, (
256), 0 }
;
190
191void pppoeintr(void)
192{
193 struct mbuf_list ml;
194 struct mbuf *m;
195
196 NET_ASSERT_LOCKED()do { int _s = rw_status(&netlock); if ((splassert_ctl >
0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail
(0x0002UL, _s, __func__); } while (0)
;
197
198 mq_delist(&pppoediscinq, &ml);
199 while ((m = ml_dequeue(&ml)) != NULL((void *)0))
200 pppoe_disc_input(m);
201
202 mq_delist(&pppoeinq, &ml);
203 while ((m = ml_dequeue(&ml)) != NULL((void *)0))
204 pppoe_data_input(m);
205}
206
207void
208pppoeattach(int count)
209{
210 LIST_INIT(&pppoe_softc_list)do { ((&pppoe_softc_list)->lh_first) = ((void *)0); } while
(0)
;
211 if_clone_attach(&pppoe_cloner);
212}
213
214/* Create a new interface. */
215int
216pppoe_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_DEVBUF2, M_WAITOK0x0001|M_ZERO0x0008);
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_mtuif_data.ifi_mtu = PPPOE_MTU((1518 - ((6 * 2) + 2) - 4) - (sizeof(struct pppoehdr) + 2));
227 sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX0x800 | IFF_POINTOPOINT0x10 | IFF_MULTICAST0x8000;
228 sc->sc_sppp.pp_if.if_typeif_data.ifi_type = IFT_PPP0x17;
229 sc->sc_sppp.pp_if.if_hdrlenif_data.ifi_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLENsizeof(struct pppoehdr);
230 sc->sc_sppp.pp_flags |= PP_KEEPALIVE0x01; /* use LCP keepalive */
231 sc->sc_sppp.pp_framebytes = PPPOE_HEADERLENsizeof(struct pppoehdr); /* 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_CLONED0x2;
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))__builtin_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 NBPFILTER1 > 0
249 bpfattach(&sc->sc_sppp.pp_if.if_bpf, &sc->sc_sppp.pp_if, DLT_PPP_ETHER51, 0);
250#endif
251
252 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
253retry:
254 unique = arc4random();
255 LIST_FOREACH(tmpsc, &pppoe_softc_list, sc_list)for((tmpsc) = ((&pppoe_softc_list)->lh_first); (tmpsc)
!= ((void *)0); (tmpsc) = ((tmpsc)->sc_list.le_next))
256 if (tmpsc->sc_unique == unique)
257 goto retry;
258 sc->sc_unique = unique;
259 LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list)do { if (((sc)->sc_list.le_next = (&pppoe_softc_list)->
lh_first) != ((void *)0)) (&pppoe_softc_list)->lh_first
->sc_list.le_prev = &(sc)->sc_list.le_next; (&pppoe_softc_list
)->lh_first = (sc); (sc)->sc_list.le_prev = &(&
pppoe_softc_list)->lh_first; } while (0)
;
260 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
261
262 return (0);
263}
264
265/* Destroy a given interface. */
266int
267pppoe_clone_destroy(struct ifnet *ifp)
268{
269 struct pppoe_softc *sc = ifp->if_softc;
270
271 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
272 LIST_REMOVE(sc, sc_list)do { if ((sc)->sc_list.le_next != ((void *)0)) (sc)->sc_list
.le_next->sc_list.le_prev = (sc)->sc_list.le_prev; *(sc
)->sc_list.le_prev = (sc)->sc_list.le_next; ((sc)->sc_list
.le_prev) = ((void *)-1); ((sc)->sc_list.le_next) = ((void
*)-1); } while (0)
;
273 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
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_DEVBUF2,
282 strlen(sc->sc_concentrator_name) + 1);
283 if (sc->sc_service_name)
284 free(sc->sc_service_name, M_DEVBUF2,
285 strlen(sc->sc_service_name) + 1);
286 if (sc->sc_ac_cookie)
287 free(sc->sc_ac_cookie, M_DEVBUF2, sc->sc_ac_cookie_len);
288 if (sc->sc_relay_sid)
289 free(sc->sc_relay_sid, M_DEVBUF2, sc->sc_relay_sid_len);
290
291 free(sc, M_DEVBUF2, 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 */
302static struct pppoe_softc *
303pppoe_find_softc_by_session(u_int session, u_int ifidx)
304{
305 struct pppoe_softc *sc;
306
307 if (session == 0)
308 return (NULL((void *)0));
309
310 LIST_FOREACH(sc, &pppoe_softc_list, sc_list)for((sc) = ((&pppoe_softc_list)->lh_first); (sc)!= ((void
*)0); (sc) = ((sc)->sc_list.le_next))
{
311 if (sc->sc_state == PPPOE_STATE_SESSION3
312 && sc->sc_session == session
313 && sc->sc_eth_ifidx == ifidx) {
314 return (sc);
315 }
316 }
317 return (NULL((void *)0));
318}
319
320/*
321 * Check host unique token passed and return appropriate softc pointer,
322 * or NULL if token is bogus.
323 */
324static struct pppoe_softc *
325pppoe_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)(((&pppoe_softc_list)->lh_first) == ((void *)0)))
331 return (NULL((void *)0));
332
333 if (len != sizeof(hunique))
334 return (NULL((void *)0));
335 memcpy(&hunique, token, len)__builtin_memcpy((&hunique), (token), (len));
336
337 LIST_FOREACH(sc, &pppoe_softc_list, sc_list)for((sc) = ((&pppoe_softc_list)->lh_first); (sc)!= ((void
*)0); (sc) = ((sc)->sc_list.le_next))
338 if (sc->sc_unique == hunique)
339 break;
340
341 if (sc == NULL((void *)0)) {
342 printf("pppoe: alien host unique tag, no session found\n");
343 return (NULL((void *)0));
344 }
345
346 /* should be safe to access *sc now */
347 if (sc->sc_state < PPPOE_STATE_PADI_SENT1 || sc->sc_state >= PPPOE_STATE_SESSION3) {
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((void *)0));
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((void *)0));
356 }
357 return (sc);
358}
359
360/* Analyze and handle a single received packet while not in session state. */
361static void
362pppoe_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((void *)0);
381 devname = "pppoe";
382 off = 0;
383 errortag = 0;
384 max_payloadtag = 0;
385
386 if (m->m_lenm_hdr.mh_len < sizeof(*eh)) {
1
Assuming the condition is false
2
Taking false branch
387 m = m_pullup(m, sizeof(*eh));
388 if (m == NULL((void *)0))
389 goto done;
390 }
391 eh = mtod(m, struct ether_header *)((struct ether_header *)((m)->m_hdr.mh_data));
392 off += sizeof(*eh);
393
394 ac_cookie = NULL((void *)0);
395 ac_cookie_len = 0;
396 relay_sid = NULL((void *)0);
397 relay_sid_len = 0;
398 max_payload = 0;
399
400 session = 0;
401 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len - off <= PPPOE_HEADERLENsizeof(struct pppoehdr)) {
3
Assuming the condition is false
4
Taking false branch
402 printf("pppoe: packet too short: %d\n", m->m_pkthdrM_dat.MH.MH_pkthdr.len);
403 goto done;
404 }
405
406 n = m_pulldown(m, off, sizeof(*ph), &noff);
407 if (n == NULL((void *)0)) {
5
Assuming 'n' is not equal to NULL
6
Taking false branch
408 printf("pppoe: could not get PPPoE header\n");
409 m = NULL((void *)0);
410 goto done;
411 }
412 ph = (struct pppoehdr *)(mtod(n, caddr_t)((caddr_t)((n)->m_hdr.mh_data)) + noff);
413 if (ph->vertype != PPPOE_VERTYPE0x11) {
7
Assuming field 'vertype' is equal to 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)(__uint16_t)(__builtin_constant_p(ph->session) ? (__uint16_t
)(((__uint16_t)(ph->session) & 0xffU) << 8 | ((__uint16_t
)(ph->session) & 0xff00U) >> 8) : __swap16md(ph->
session))
;
8
Taking false branch
9
'?' condition is false
420 plen = ntohs(ph->plen)(__uint16_t)(__builtin_constant_p(ph->plen) ? (__uint16_t)
(((__uint16_t)(ph->plen) & 0xffU) << 8 | ((__uint16_t
)(ph->plen) & 0xff00U) >> 8) : __swap16md(ph->
plen))
;
10
'?' condition is false
421 code = ph->code;
422 off += sizeof(*ph);
423 if (plen + off > m->m_pkthdrM_dat.MH.MH_pkthdr.len) {
11
Assuming the condition is false
12
Taking false branch
424 printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
425 m->m_pkthdrM_dat.MH.MH_pkthdr.len - off, plen);
426 goto done;
427 }
428
429 /* ignore trailing garbage */
430 m_adj(m, off + plen - m->m_pkthdrM_dat.MH.MH_pkthdr.len);
431
432 tag = 0;
433 len = 0;
434 sc = NULL((void *)0);
435 while (off + sizeof(*pt) <= m->m_pkthdrM_dat.MH.MH_pkthdr.len) {
13
Assuming the condition is true
14
Loop condition is true. Entering loop body
28
Assuming the condition is false
29
Loop condition is false. Execution continues on line 544
436 n = m_pulldown(m, off, sizeof(*pt), &noff);
437 if (n == NULL((void *)0)) {
15
Assuming 'n' is not equal to NULL
16
Taking false branch
438 printf("%s: parse error\n", devname);
439 m = NULL((void *)0);
440 goto done;
441 }
442 pt = (struct pppoetag *)(mtod(n, caddr_t)((caddr_t)((n)->m_hdr.mh_data)) + noff);
443 tag = ntohs(pt->tag)(__uint16_t)(__builtin_constant_p(pt->tag) ? (__uint16_t)(
((__uint16_t)(pt->tag) & 0xffU) << 8 | ((__uint16_t
)(pt->tag) & 0xff00U) >> 8) : __swap16md(pt->
tag))
;
17
'?' condition is false
444 len = ntohs(pt->len)(__uint16_t)(__builtin_constant_p(pt->len) ? (__uint16_t)(
((__uint16_t)(pt->len) & 0xffU) << 8 | ((__uint16_t
)(pt->len) & 0xff00U) >> 8) : __swap16md(pt->
len))
;
18
'?' condition is false
445 off += sizeof(*pt);
446 if (off + len > m->m_pkthdrM_dat.MH.MH_pkthdr.len) {
19
Assuming the condition is false
20
Taking false branch
447 printf("%s: tag 0x%x len 0x%x is too long\n",
448 devname, tag, len);
449 goto done;
450 }
451 switch (tag) {
21
Control jumps to 'case 259:' at line 458
452 case PPPOE_TAG_EOL0x0000:
453 goto breakbreak;
454 case PPPOE_TAG_SNAME0x0101:
455 break; /* ignored */
456 case PPPOE_TAG_ACNAME0x0102:
457 break; /* ignored */
458 case PPPOE_TAG_HUNIQUE0x0103:
459 if (sc
21.1
'sc' is equal to NULL
!= NULL((void *)0))
22
Taking false branch
460 break;
461 n = m_pulldown(m, off, len, &noff);
462 if (n == NULL((void *)0)) {
23
Assuming 'n' is not equal to NULL
24
Taking false branch
463 m = NULL((void *)0);
464 err_msg = "TAG HUNIQUE ERROR";
465 break;
466 }
467 sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t)((caddr_t)((n)->m_hdr.mh_data)) + noff,
468 len, m->m_pkthdrM_dat.MH.MH_pkthdr.ph_ifidx);
469 if (sc
24.1
'sc' is not equal to NULL
!= NULL((void *)0))
25
Taking true branch
470 devname = sc->sc_sppp.pp_if.if_xname;
471 break;
472 case PPPOE_TAG_ACCOOKIE0x0104:
473 if (ac_cookie == NULL((void *)0)) {
474 n = m_pulldown(m, off, len,
475 &noff);
476 if (n == NULL((void *)0)) {
477 err_msg = "TAG ACCOOKIE ERROR";
478 m = NULL((void *)0);
479 break;
480 }
481 ac_cookie = mtod(n, caddr_t)((caddr_t)((n)->m_hdr.mh_data)) + noff;
482 ac_cookie_len = len;
483 }
484 break;
485 case PPPOE_TAG_RELAYSID0x0110:
486 if (relay_sid == NULL((void *)0)) {
487 n = m_pulldown(m, off, len,
488 &noff);
489 if (n == NULL((void *)0)) {
490 err_msg = "TAG RELAYSID ERROR";
491 m = NULL((void *)0);
492 break;
493 }
494 relay_sid = mtod(n, caddr_t)((caddr_t)((n)->m_hdr.mh_data)) + noff;
495 relay_sid_len = len;
496 }
497 break;
498 case PPPOE_TAG_MAX_PAYLOAD0x0120:
499 if (!max_payloadtag) {
500 n = m_pulldown(m, off, len,
501 &noff);
502 if (n == NULL((void *)0) || len != sizeof(max_payload)) {
503 err_msg = "TAG MAX_PAYLOAD ERROR";
504 m = NULL((void *)0);
505 break;
506 }
507 memcpy(&max_payload, mtod(n, caddr_t) + noff,__builtin_memcpy((&max_payload), (((caddr_t)((n)->m_hdr
.mh_data)) + noff), (sizeof(max_payload)))
508 sizeof(max_payload))__builtin_memcpy((&max_payload), (((caddr_t)((n)->m_hdr
.mh_data)) + noff), (sizeof(max_payload)))
;
509 max_payloadtag = 1;
510 }
511 break;
512 case PPPOE_TAG_SNAME_ERR0x0201:
513 err_msg = "SERVICE NAME ERROR";
514 errortag = 1;
515 break;
516 case PPPOE_TAG_ACSYS_ERR0x0202:
517 err_msg = "AC SYSTEM ERROR";
518 errortag = 1;
519 break;
520 case PPPOE_TAG_GENERIC_ERR0x0203:
521 err_msg = "GENERIC ERROR";
522 errortag = 1;
523 break;
524 }
525 if (err_msg
26.1
'err_msg' is null
) {
26
Execution continues on line 525
27
Taking false branch
526 log(LOG_INFO6, "%s: %s: ", devname, err_msg);
527 if (errortag && len) {
528 n = m_pulldown(m, off, len,
529 &noff);
530 if (n == NULL((void *)0)) {
531 m = NULL((void *)0);
532 } else {
533 u_int8_t *et = mtod(n, caddr_t)((caddr_t)((n)->m_hdr.mh_data)) + noff;
534 while (len--)
535 addlog("%c", *et++);
536 }
537 }
538 addlog("\n");
539 goto done;
540 }
541 off += len;
542 }
543breakbreak:
544 switch (code) {
30
Control jumps to 'case 7:' at line 549
545 case PPPOE_CODE_PADI0x09:
546 case PPPOE_CODE_PADR0x19:
547 /* ignore, we are no access concentrator */
548 goto done;
549 case PPPOE_CODE_PADO0x07:
550 if (sc
30.1
'sc' is not equal to NULL
== NULL((void *)0)) {
31
Taking false branch
551 /* be quiet if there is not a single pppoe instance */
552 if (!LIST_EMPTY(&pppoe_softc_list)(((&pppoe_softc_list)->lh_first) == ((void *)0)))
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_SENT1) {
32
Assuming field 'sc_state' is equal to PPPOE_STATE_PADI_SENT
33
Taking false branch
557 printf("%s: received unexpected PADO\n",
558 sc->sc_sppp.pp_if.if_xname);
559 goto done;
560 }
561 if (ac_cookie
33.1
'ac_cookie' is null
) {
34
Taking false branch
562 if (sc->sc_ac_cookie)
563 free(sc->sc_ac_cookie, M_DEVBUF2,
564 sc->sc_ac_cookie_len);
565 sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF2,
566 M_DONTWAIT0x0002);
567 if (sc->sc_ac_cookie == NULL((void *)0)) {
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)__builtin_memcpy((sc->sc_ac_cookie), (ac_cookie), (ac_cookie_len
))
;
573 } else if (sc->sc_ac_cookie) {
35
Assuming field 'sc_ac_cookie' is null
36
Taking false branch
574 free(sc->sc_ac_cookie, M_DEVBUF2, sc->sc_ac_cookie_len);
575 sc->sc_ac_cookie = NULL((void *)0);
576 sc->sc_ac_cookie_len = 0;
577 }
578 if (relay_sid
36.1
'relay_sid' is null
) {
37
Taking false branch
579 if (sc->sc_relay_sid)
580 free(sc->sc_relay_sid, M_DEVBUF2,
581 sc->sc_relay_sid_len);
582 sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF2,
583 M_DONTWAIT0x0002);
584 if (sc->sc_relay_sid == NULL((void *)0)) {
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)__builtin_memcpy((sc->sc_relay_sid), (relay_sid), (relay_sid_len
))
;
590 } else if (sc->sc_relay_sid) {
38
Assuming field 'sc_relay_sid' is null
591 free(sc->sc_relay_sid, M_DEVBUF2, sc->sc_relay_sid_len);
592 sc->sc_relay_sid = NULL((void *)0);
593 sc->sc_relay_sid_len = 0;
594 }
595 if (sc->sc_sppp.pp_if.if_mtuif_data.ifi_mtu > PPPOE_MTU((1518 - ((6 * 2) + 2) - 4) - (sizeof(struct pppoehdr) + 2)) &&
39
Assuming the condition is false
596 (!max_payloadtag ||
597 ntohs(max_payload)(__uint16_t)(__builtin_constant_p(max_payload) ? (__uint16_t)
(((__uint16_t)(max_payload) & 0xffU) << 8 | ((__uint16_t
)(max_payload) & 0xff00U) >> 8) : __swap16md(max_payload
))
!= sc->sc_sppp.pp_if.if_mtuif_data.ifi_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_mtuif_data.ifi_mtu = PPPOE_MTU((1518 - ((6 * 2) + 2) - 4) - (sizeof(struct pppoehdr) + 2));
601 }
602
603 memcpy(&sc->sc_dest, eh->ether_shost, sizeof(sc->sc_dest))__builtin_memcpy((&sc->sc_dest), (eh->ether_shost),
(sizeof(sc->sc_dest)))
;
604 sc->sc_padr_retried = 0;
605 sc->sc_state = PPPOE_STATE_PADR_SENT2;
606 if ((err = pppoe_send_padr(sc)) != 0) {
40
Calling 'pppoe_send_padr'
607 PPPOEDEBUG(("%s: failed to send PADR, error=%d\n",((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to send PADR, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
608 sc->sc_sppp.pp_if.if_xname, err))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to send PADR, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
;
609 }
610 timeout_add_sec(&sc->sc_timeout,
611 PPPOE_DISC_TIMEOUT5 * (1 + sc->sc_padr_retried));
612
613 break;
614 case PPPOE_CODE_PADS0x65:
615 if (sc == NULL((void *)0))
616 goto done;
617
618 sc->sc_session = session;
619 timeout_del(&sc->sc_timeout);
620 PPPOEDEBUG(("%s: session 0x%x connected\n",((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: session 0x%x connected\n"
, sc->sc_sppp.pp_if.if_xname, session) : 0)
621 sc->sc_sppp.pp_if.if_xname, session))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: session 0x%x connected\n"
, sc->sc_sppp.pp_if.if_xname, session) : 0)
;
622 sc->sc_state = PPPOE_STATE_SESSION3;
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_PADT0xA7:
628 if (sc == NULL((void *)0))
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",((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: session 0x%x terminated, received PADT\n"
, sc->sc_sppp.pp_if.if_xname, session) : 0)
634 sc->sc_sppp.pp_if.if_xname, session))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: session 0x%x terminated, received PADT\n"
, sc->sc_sppp.pp_if.if_xname, session) : 0)
;
635
636 /* clean up softc */
637 sc->sc_state = PPPOE_STATE_INITIAL0;
638 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest))__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
;
639 if (sc->sc_ac_cookie) {
640 free(sc->sc_ac_cookie, M_DEVBUF2,
641 sc->sc_ac_cookie_len);
642 sc->sc_ac_cookie = NULL((void *)0);
643 }
644 if (sc->sc_relay_sid) {
645 free(sc->sc_relay_sid, M_DEVBUF2, sc->sc_relay_sid_len);
646 sc->sc_relay_sid = NULL((void *)0);
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
663done:
664 m_freem(m);
665}
666
667/* Input function for discovery packets. */
668void
669pppoe_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)(((&pppoe_softc_list)->lh_first) == ((void *)0))) {
673 KASSERT(m->m_flags & M_PKTHDR)((m->m_hdr.mh_flags & 0x0002) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/net/if_pppoe.c", 673, "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 */
680void
681pppoe_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_LEN6];
688#endif
689 if (LIST_EMPTY(&pppoe_softc_list)(((&pppoe_softc_list)->lh_first) == ((void *)0)))
690 goto drop;
691
692 KASSERT(m->m_flags & M_PKTHDR)((m->m_hdr.mh_flags & 0x0002) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/net/if_pppoe.c", 692, "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)__builtin_memcpy((shost), (((struct ether_header*)((m)->m_hdr
.mh_data))->ether_shost), (6))
;
696#endif
697 m_adj(m, sizeof(struct ether_header));
698 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len <= PPPOE_HEADERLENsizeof(struct pppoehdr)) {
699 printf("pppoe (data): dropping too short packet: %d bytes\n",
700 m->m_pkthdrM_dat.MH.MH_pkthdr.len);
701 goto drop;
702 }
703 if (m->m_lenm_hdr.mh_len < sizeof(*ph)) {
704 m = m_pullup(m, sizeof(*ph));
705 if (m == NULL((void *)0)) {
706 printf("pppoe (data): could not get PPPoE header\n");
707 return;
708 }
709 }
710 ph = mtod(m, struct pppoehdr *)((struct pppoehdr *)((m)->m_hdr.mh_data));
711 if (ph->vertype != PPPOE_VERTYPE0x11) {
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)(__uint16_t)(__builtin_constant_p(ph->session) ? (__uint16_t
)(((__uint16_t)(ph->session) & 0xffU) << 8 | ((__uint16_t
)(ph->session) & 0xff00U) >> 8) : __swap16md(ph->
session))
;
720 sc = pppoe_find_softc_by_session(session, m->m_pkthdrM_dat.MH.MH_pkthdr.ph_ifidx);
721 if (sc == NULL((void *)0)) {
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_pkthdrM_dat.MH.MH_pkthdr.ph_ifidx, session, shost, 0);
726#endif
727 goto drop;
728 }
729
730 plen = ntohs(ph->plen)(__uint16_t)(__builtin_constant_p(ph->plen) ? (__uint16_t)
(((__uint16_t)(ph->plen) & 0xffU) << 8 | ((__uint16_t
)(ph->plen) & 0xff00U) >> 8) : __swap16md(ph->
plen))
;
731
732#if NBPFILTER1 > 0
733 if(sc->sc_sppp.pp_if.if_bpf)
734 bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m, BPF_DIRECTION_IN(1 << 0));
735#endif
736
737 m_adj(m, PPPOE_HEADERLENsizeof(struct pppoehdr));
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_pkthdrM_dat.MH.MH_pkthdr.len, plen);
746 p = m;
747 while (p) {
748 printf(" l=%d", p->m_lenm_hdr.mh_len);
749 p = p->m_nextm_hdr.mh_next;
750 }
751 printf("\n");
752 }
753#endif
754
755 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len < plen)
756 goto drop;
757
758 /* fix incoming interface pointer (not the raw ethernet interface anymore) */
759 m->m_pkthdrM_dat.MH.MH_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_ipacketsif_data.ifi_ipackets++;
763 sppp_input(&sc->sc_sppp.pp_if, m);
764 return;
765
766drop:
767 m_freem(m);
768}
769
770static int
771pppoe_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((void *)0)) {
780 m_freem(m);
781 return (EIO5);
782 }
783
784 if ((eth_if->if_flags & (IFF_UP0x1|IFF_RUNNING0x40))
785 != (IFF_UP0x1|IFF_RUNNING0x40)) {
786 if_put(eth_if);
787 m_freem(m);
788 return (ENETDOWN50);
789 }
790
791 memset(&dst, 0, sizeof dst)__builtin_memset((&dst), (0), (sizeof dst));
792 dst.sa_family = AF_UNSPEC0;
793 eh = (struct ether_header*)&dst.sa_data;
794 etype = sc->sc_state == PPPOE_STATE_SESSION3 ? ETHERTYPE_PPPOE0x8864 : ETHERTYPE_PPPOEDISC0x8863;
795 eh->ether_type = htons(etype)(__uint16_t)(__builtin_constant_p(etype) ? (__uint16_t)(((__uint16_t
)(etype) & 0xffU) << 8 | ((__uint16_t)(etype) &
0xff00U) >> 8) : __swap16md(etype))
;
796 memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest)__builtin_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",((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n"
, sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->
sc_session, ether_sprintf((unsigned char *)&sc->sc_dest
), m->M_dat.MH.MH_pkthdr.len) : 0)
799 sc->sc_sppp.pp_if.if_xname, etype,((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n"
, sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->
sc_session, ether_sprintf((unsigned char *)&sc->sc_dest
), m->M_dat.MH.MH_pkthdr.len) : 0)
800 sc->sc_state, sc->sc_session,((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n"
, sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->
sc_session, ether_sprintf((unsigned char *)&sc->sc_dest
), m->M_dat.MH.MH_pkthdr.len) : 0)
801 ether_sprintf((unsigned char *)&sc->sc_dest), m->m_pkthdr.len))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n"
, sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->
sc_session, ether_sprintf((unsigned char *)&sc->sc_dest
), m->M_dat.MH.MH_pkthdr.len) : 0)
;
802
803 m->m_flagsm_hdr.mh_flags &= ~(M_BCAST0x0100|M_MCAST0x0200);
804 /* encapsulated packet is forced into rdomain of physical interface */
805 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid = eth_if->if_rdomainif_data.ifi_rdomain;
806
807 ret = eth_if->if_output(eth_if, m, &dst, NULL((void *)0));
808 if_put(eth_if);
809
810 return (ret);
811}
812
813/* The ioctl routine. */
814static int
815pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
816{
817 struct proc *p = curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_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((unsigned long)0x80000000 | ((sizeof(struct pppoediscparms) &
0x1fff) << 16) | ((('i')) << 8) | ((110)))
:
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((void *)0) || eth_if->if_typeif_data.ifi_type != IFT_ETHER0x06) {
835 if_put(eth_if);
836 sc->sc_eth_ifidx = 0;
837 return (ENXIO6);
838 }
839
840 if (sc->sc_sppp.pp_if.if_mtuif_data.ifi_mtu >
841 eth_if->if_mtuif_data.ifi_mtu - PPPOE_OVERHEAD(sizeof(struct pppoehdr) + 2)) {
842 sc->sc_sppp.pp_if.if_mtuif_data.ifi_mtu = eth_if->if_mtuif_data.ifi_mtu -
843 PPPOE_OVERHEAD(sizeof(struct pppoehdr) + 2);
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_DEVBUF2,
851 strlen(sc->sc_concentrator_name) + 1);
852 sc->sc_concentrator_name = NULL((void *)0);
853
854 len = strlen(parms->ac_name);
855 if (len > 0 && len < sizeof(parms->ac_name)) {
856 char *p = malloc(len + 1, M_DEVBUF2, M_WAITOK0x0001|M_CANFAIL0x0004);
857 if (p == NULL((void *)0))
858 return (ENOMEM12);
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_DEVBUF2,
865 strlen(sc->sc_service_name) + 1);
866 sc->sc_service_name = NULL((void *)0);
867
868 len = strlen(parms->service_name);
869 if (len > 0 && len < sizeof(parms->service_name)) {
870 char *p = malloc(len + 1, M_DEVBUF2, M_WAITOK0x0001|M_CANFAIL0x0004);
871 if (p == NULL((void *)0))
872 return (ENOMEM12);
873 strlcpy(p, parms->service_name, len + 1);
874 sc->sc_service_name = p;
875 }
876 return (0);
877 }
878 break;
879 case PPPOEGETPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct pppoediscparms) & 0x1fff) << 16) | ((('i'))
<< 8) | ((111)))
:
880 {
881 struct pppoediscparms *parms = (struct pppoediscparms *)data;
882
883 if ((eth_if = if_get(sc->sc_eth_ifidx)) != NULL((void *)0)) {
884 strlcpy(parms->eth_ifname, eth_if->if_xname,
885 IFNAMSIZ16);
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(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct pppoeconnectionstate) & 0x1fff) << 16) | ((
('i')) << 8) | ((112)))
:
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((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
919 {
920 struct ifreq *ifr = (struct ifreq *)data;
921 /*
922 * Prevent running re-establishment timers overriding
923 * administrators choice.
924 */
925 if ((ifr->ifr_flagsifr_ifru.ifru_flags & IFF_UP0x1) == 0
926 && sc->sc_state >= PPPOE_STATE_PADI_SENT1
927 && sc->sc_state < PPPOE_STATE_SESSION3) {
928 timeout_del(&sc->sc_timeout);
929 sc->sc_state = PPPOE_STATE_INITIAL0;
930 sc->sc_padi_retried = 0;
931 sc->sc_padr_retried = 0;
932 memcpy(&sc->sc_dest, etherbroadcastaddr,__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
933 sizeof(sc->sc_dest))__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
;
934 }
935 return (sppp_ioctl(ifp, cmd, data));
936 }
937 case SIOCSIFMTU((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((127)))
:
938 {
939 struct ifreq *ifr = (struct ifreq *)data;
940
941 eth_if = if_get(sc->sc_eth_ifidx);
942
943 if (ifr->ifr_mtuifr_ifru.ifru_metric > MIN(PPPOE_MAXMTU,(((2048)<((eth_if == ((void *)0) ? 2048 : (eth_if->if_data
.ifi_mtu - (sizeof(struct pppoehdr) + 2)))))?(2048):((eth_if ==
((void *)0) ? 2048 : (eth_if->if_data.ifi_mtu - (sizeof(struct
pppoehdr) + 2)))))
944 (eth_if == NULL ? PPPOE_MAXMTU :(((2048)<((eth_if == ((void *)0) ? 2048 : (eth_if->if_data
.ifi_mtu - (sizeof(struct pppoehdr) + 2)))))?(2048):((eth_if ==
((void *)0) ? 2048 : (eth_if->if_data.ifi_mtu - (sizeof(struct
pppoehdr) + 2)))))
945 (eth_if->if_mtu - PPPOE_OVERHEAD)))(((2048)<((eth_if == ((void *)0) ? 2048 : (eth_if->if_data
.ifi_mtu - (sizeof(struct pppoehdr) + 2)))))?(2048):((eth_if ==
((void *)0) ? 2048 : (eth_if->if_data.ifi_mtu - (sizeof(struct
pppoehdr) + 2)))))
)
946 error = EINVAL22;
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 == ENETRESET52) {
960 error = 0;
961 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
962 (IFF_UP0x1 | IFF_RUNNING0x40)) {
963 if_down(ifp);
964 if (sc->sc_state >= PPPOE_STATE_PADI_SENT1 &&
965 sc->sc_state < PPPOE_STATE_SESSION3) {
966 timeout_del(&sc->sc_timeout);
967 sc->sc_state = PPPOE_STATE_INITIAL0;
968 sc->sc_padi_retried = 0;
969 sc->sc_padr_retried = 0;
970 memcpy(&sc->sc_dest,__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
971 etherbroadcastaddr,__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
972 sizeof(sc->sc_dest))__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
;
973 }
974 error = sppp_ioctl(ifp, SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
, NULL((void *)0));
975 if (error)
976 return (error);
977 if_up(ifp);
978 return (sppp_ioctl(ifp, SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
, NULL((void *)0)));
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 */
991static struct mbuf *
992pppoe_get_mbuf(size_t len)
993{
994 struct mbuf *m;
995
996 if (len + sizeof(struct ether_header) > MCLBYTES(1 << 11))
997 return NULL((void *)0);
998
999 MGETHDR(m, M_DONTWAIT, MT_DATA)m = m_gethdr((0x0002), (1));
1000 if (m == NULL((void *)0))
1001 return (NULL((void *)0));
1002 if (len + sizeof(struct ether_header) > MHLEN((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) {
1003 MCLGET(m, M_DONTWAIT)(void) m_clget((m), (0x0002), (1 << 11));
1004 if ((m->m_flagsm_hdr.mh_flags & M_EXT0x0001) == 0) {
1005 m_free(m);
1006 return (NULL((void *)0));
1007 }
1008 }
1009 m->m_datam_hdr.mh_data += sizeof(struct ether_header);
1010 m->m_lenm_hdr.mh_len = len;
1011 m->m_pkthdrM_dat.MH.MH_pkthdr.len = len;
1012 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_ifidx = 0;
1013
1014 return (m);
1015}
1016
1017/* Send PADI. */
1018static int
1019pppoe_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_SENT1)
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((void *)0)) {
1031 l1 = strlen(sc->sc_service_name);
1032 len += l1;
1033 }
1034 if (sc->sc_concentrator_name != NULL((void *)0)) {
1035 l2 = strlen(sc->sc_concentrator_name);
1036 len += 2 + 2 + l2;
1037 }
1038 if (sc->sc_sppp.pp_if.if_mtuif_data.ifi_mtu > PPPOE_MTU((1518 - ((6 * 2) + 2) - 4) - (sizeof(struct pppoehdr) + 2)))
1039 len += 2 + 2 + 2;
1040
1041 /* allocate a buffer */
1042 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLENsizeof(struct pppoehdr)); /* header len + payload len */
1043 if (m0 == NULL((void *)0))
1044 return (ENOBUFS55);
1045 m0->m_pkthdrM_dat.MH.MH_pkthdr.pf.prio = sc->sc_sppp.pp_if.if_llprio;
1046
1047 /* fill in pkt */
1048 p = mtod(m0, u_int8_t *)((u_int8_t *)((m0)->m_hdr.mh_data));
1049 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len)*(p)++ = 0x11; *(p)++ = (0x09); *(p)++ = (0) / 256; *(p)++ = (
0) % 256; *(p)++ = (len) / 256; *(p)++ = (len) % 256
;
1050 PPPOE_ADD_16(p, PPPOE_TAG_SNAME)*(p)++ = (0x0101) / 256; *(p)++ = (0x0101) % 256;
1051 if (sc->sc_service_name != NULL((void *)0)) {
1052 PPPOE_ADD_16(p, l1)*(p)++ = (l1) / 256; *(p)++ = (l1) % 256;
1053 memcpy(p, sc->sc_service_name, l1)__builtin_memcpy((p), (sc->sc_service_name), (l1));
1054 p += l1;
1055 } else {
1056 PPPOE_ADD_16(p, 0)*(p)++ = (0) / 256; *(p)++ = (0) % 256;
1057 }
1058 if (sc->sc_concentrator_name != NULL((void *)0)) {
1059 PPPOE_ADD_16(p, PPPOE_TAG_ACNAME)*(p)++ = (0x0102) / 256; *(p)++ = (0x0102) % 256;
1060 PPPOE_ADD_16(p, l2)*(p)++ = (l2) / 256; *(p)++ = (l2) % 256;
1061 memcpy(p, sc->sc_concentrator_name, l2)__builtin_memcpy((p), (sc->sc_concentrator_name), (l2));
1062 p += l2;
1063 }
1064 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE)*(p)++ = (0x0103) / 256; *(p)++ = (0x0103) % 256;
1065 PPPOE_ADD_16(p, sizeof(sc->sc_unique))*(p)++ = (sizeof(sc->sc_unique)) / 256; *(p)++ = (sizeof(sc
->sc_unique)) % 256
;
1066 memcpy(p, &sc->sc_unique, sizeof(sc->sc_unique))__builtin_memcpy((p), (&sc->sc_unique), (sizeof(sc->
sc_unique)))
;
1067 p += sizeof(sc->sc_unique);
1068
1069 if (sc->sc_sppp.pp_if.if_mtuif_data.ifi_mtu > PPPOE_MTU((1518 - ((6 * 2) + 2) - 4) - (sizeof(struct pppoehdr) + 2))) {
1070 PPPOE_ADD_16(p, PPPOE_TAG_MAX_PAYLOAD)*(p)++ = (0x0120) / 256; *(p)++ = (0x0120) % 256;
1071 PPPOE_ADD_16(p, 2)*(p)++ = (2) / 256; *(p)++ = (2) % 256;
1072 PPPOE_ADD_16(p, (u_int16_t)sc->sc_sppp.pp_if.if_mtu)*(p)++ = ((u_int16_t)sc->sc_sppp.pp_if.if_data.ifi_mtu) / 256
; *(p)++ = ((u_int16_t)sc->sc_sppp.pp_if.if_data.ifi_mtu) %
256
;
1073 }
1074
1075#ifdef PPPOE_DEBUG
1076 if (p - mtod(m0, u_int8_t *)((u_int8_t *)((m0)->m_hdr.mh_data)) != len + PPPOE_HEADERLENsizeof(struct pppoehdr))
1077 panic("pppoe_send_padi: garbled output len, should be %ld, is %ld",
1078 (long)(len + PPPOE_HEADERLENsizeof(struct pppoehdr)), (long)(p - mtod(m0, u_int8_t *)((u_int8_t *)((m0)->m_hdr.mh_data))));
1079#endif
1080
1081 /* send pkt */
1082 return (pppoe_output(sc, m0));
1083}
1084
1085/* Watchdog function. */
1086static void
1087pppoe_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))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: timeout\n"
, sc->sc_sppp.pp_if.if_xname) : 0)
;
1093
1094 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1095
1096 switch (sc->sc_state) {
1097 case PPPOE_STATE_PADI_SENT1:
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_TIMEOUT5 * (1 + sc->sc_padi_retried);
1110
1111 x = splnet()splraise(0x4);
1112 sc->sc_padi_retried++;
1113 if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI4) {
1114 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK10x2000) == 0) {
1115 /* slow retry mode */
1116 retry_wait = PPPOE_SLOW_RETRY60;
1117 } else {
1118 pppoe_abort_connect(sc);
1119 splx(x)spllower(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",((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to transmit PADI, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
1126 sc->sc_sppp.pp_if.if_xname, err))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to transmit PADI, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
;
1127 }
1128 timeout_add_sec(&sc->sc_timeout, retry_wait);
1129 splx(x)spllower(x);
1130
1131 break;
1132 case PPPOE_STATE_PADR_SENT2:
1133 x = splnet()splraise(0x4);
1134 sc->sc_padr_retried++;
1135 if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR2) {
1136 memcpy(&sc->sc_dest, etherbroadcastaddr,__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
1137 sizeof(sc->sc_dest))__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
;
1138 sc->sc_state = PPPOE_STATE_PADI_SENT1;
1139 sc->sc_padr_retried = 0;
1140 if ((err = pppoe_send_padi(sc)) != 0) {
1141 PPPOEDEBUG(("%s: failed to send PADI, error=%d\n",((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to send PADI, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
1142 sc->sc_sppp.pp_if.if_xname, err))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to send PADI, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
;
1143 }
1144 timeout_add_sec(&sc->sc_timeout,
1145 PPPOE_DISC_TIMEOUT5 * (1 + sc->sc_padi_retried));
1146 splx(x)spllower(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",((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to send PADR, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
1152 sc->sc_sppp.pp_if.if_xname, err))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to send PADR, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
;
1153 }
1154 timeout_add_sec(&sc->sc_timeout,
1155 PPPOE_DISC_TIMEOUT5 * (1 + sc->sc_padr_retried));
1156 splx(x)spllower(x);
1157
1158 break;
1159 case PPPOE_STATE_CLOSING4:
1160 pppoe_disconnect(sc);
1161 break;
1162 default:
1163 break; /* all done, work in peace */
1164 }
1165
1166 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1167}
1168
1169/* Start a connection (i.e. initiate discovery phase). */
1170static int
1171pppoe_connect(struct pppoe_softc *sc)
1172{
1173 int x, err;
1174
1175 if (sc->sc_state != PPPOE_STATE_INITIAL0)
1176 return (EBUSY16);
1177
1178 x = splnet()splraise(0x4);
1179
1180 /* save state, in case we fail to send PADI */
1181 sc->sc_state = PPPOE_STATE_PADI_SENT1;
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",((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to send PADI, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
1186 sc->sc_sppp.pp_if.if_xname, err))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: failed to send PADI, error=%d\n"
, sc->sc_sppp.pp_if.if_xname, err) : 0)
;
1187
1188 timeout_add_sec(&sc->sc_timeout, PPPOE_DISC_TIMEOUT5);
1189 splx(x)spllower(x);
1190
1191 return (err);
1192}
1193
1194/* disconnect */
1195static int
1196pppoe_disconnect(struct pppoe_softc *sc)
1197{
1198 int err, x;
1199
1200 x = splnet()splraise(0x4);
1201
1202 if (sc->sc_state < PPPOE_STATE_SESSION3)
1203 err = EBUSY16;
1204 else {
1205 PPPOEDEBUG(("%s: disconnecting\n",((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: disconnecting\n"
, sc->sc_sppp.pp_if.if_xname) : 0)
1206 sc->sc_sppp.pp_if.if_xname))((sc->sc_sppp.pp_if.if_flags & 0x4) ? printf ("%s: disconnecting\n"
, sc->sc_sppp.pp_if.if_xname) : 0)
;
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_INITIAL0;
1214 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest))__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
;
1215 if (sc->sc_ac_cookie) {
1216 free(sc->sc_ac_cookie, M_DEVBUF2, sc->sc_ac_cookie_len);
1217 sc->sc_ac_cookie = NULL((void *)0);
1218 }
1219 sc->sc_ac_cookie_len = 0;
1220 if (sc->sc_relay_sid) {
1221 free(sc->sc_relay_sid, M_DEVBUF2, sc->sc_relay_sid_len);
1222 sc->sc_relay_sid = NULL((void *)0);
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)spllower(x);
1231
1232 return (err);
1233}
1234
1235/* Connection attempt aborted. */
1236static void
1237pppoe_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_CLOSING4;
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))__builtin_memcpy((&sc->sc_dest), (etherbroadcastaddr),
(sizeof(sc->sc_dest)))
;
1248 sc->sc_state = PPPOE_STATE_INITIAL0;
1249}
1250
1251/* Send a PADR packet */
1252static int
1253pppoe_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
40.1
Field 'sc_state' is equal to PPPOE_STATE_PADR_SENT
!= PPPOE_STATE_PADR_SENT2)
41
Taking false branch
1260 return (EIO5);
1261
1262 len = 2 + 2 + 2 + 2 + sizeof(sc->sc_unique); /* service name, host unique */
1263 if (sc->sc_service_name != NULL((void *)0)) { /* service name tag maybe empty */
42
Assuming field 'sc_service_name' is equal to NULL
43
Taking false branch
1264 l1 = strlen(sc->sc_service_name);
1265 len += l1;
1266 }
1267 if (sc->sc_ac_cookie_len > 0)
44
Assuming field 'sc_ac_cookie_len' is <= 0
45
Taking false branch
1268 len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */
1269 if (sc->sc_relay_sid_len > 0)
46
Assuming field 'sc_relay_sid_len' is > 0
47
Taking true branch
1270 len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */
1271 if (sc->sc_sppp.pp_if.if_mtuif_data.ifi_mtu > PPPOE_MTU((1518 - ((6 * 2) + 2) - 4) - (sizeof(struct pppoehdr) + 2)))
48
Taking false branch
1272 len += 2 + 2 + 2;
1273
1274 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLENsizeof(struct pppoehdr));
1275 if (m0
48.1
'm0' is not equal to NULL
== NULL((void *)0))
49
Taking false branch
1276 return (ENOBUFS55);
1277 m0->m_pkthdrM_dat.MH.MH_pkthdr.pf.prio = sc->sc_sppp.pp_if.if_llprio;
1278
1279 p = mtod(m0, u_int8_t *)((u_int8_t *)((m0)->m_hdr.mh_data));
1280 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len)*(p)++ = 0x11; *(p)++ = (0x19); *(p)++ = (0) / 256; *(p)++ = (
0) % 256; *(p)++ = (len) / 256; *(p)++ = (len) % 256
;
1281 PPPOE_ADD_16(p, PPPOE_TAG_SNAME)*(p)++ = (0x0101) / 256; *(p)++ = (0x0101) % 256;
1282
1283 if (sc->sc_service_name
49.1
Field 'sc_service_name' is equal to NULL
!= NULL((void *)0)) {
50
Taking false branch
1284 PPPOE_ADD_16(p, l1)*(p)++ = (l1) / 256; *(p)++ = (l1) % 256;
1285 memcpy(p, sc->sc_service_name, l1)__builtin_memcpy((p), (sc->sc_service_name), (l1));
1286 p += l1;
1287 } else {
1288 PPPOE_ADD_16(p, 0)*(p)++ = (0) / 256; *(p)++ = (0) % 256;
1289 }
1290 if (sc->sc_ac_cookie_len
50.1
Field 'sc_ac_cookie_len' is <= 0
> 0) {
51
Taking false branch
1291 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE)*(p)++ = (0x0104) / 256; *(p)++ = (0x0104) % 256;
1292 PPPOE_ADD_16(p, sc->sc_ac_cookie_len)*(p)++ = (sc->sc_ac_cookie_len) / 256; *(p)++ = (sc->sc_ac_cookie_len
) % 256
;
1293 memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len)__builtin_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
51.1
Field 'sc_relay_sid_len' is > 0
> 0) {
52
Taking true branch
1297 PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID)*(p)++ = (0x0110) / 256; *(p)++ = (0x0110) % 256;
1298 PPPOE_ADD_16(p, sc->sc_relay_sid_len)*(p)++ = (sc->sc_relay_sid_len) / 256; *(p)++ = (sc->sc_relay_sid_len
) % 256
;
1299 memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len)__builtin_memcpy((p), (sc->sc_relay_sid), (sc->sc_relay_sid_len
))
;
53
Null pointer passed as 2nd argument to memory copy function
1300 p += sc->sc_relay_sid_len;
1301 }
1302 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE)*(p)++ = (0x0103) / 256; *(p)++ = (0x0103) % 256;
1303 PPPOE_ADD_16(p, sizeof(sc->sc_unique))*(p)++ = (sizeof(sc->sc_unique)) / 256; *(p)++ = (sizeof(sc
->sc_unique)) % 256
;
1304 memcpy(p, &sc->sc_unique, sizeof(sc->sc_unique))__builtin_memcpy((p), (&sc->sc_unique), (sizeof(sc->
sc_unique)))
;
1305 p += sizeof(sc->sc_unique);
1306
1307 if (sc->sc_sppp.pp_if.if_mtuif_data.ifi_mtu > PPPOE_MTU((1518 - ((6 * 2) + 2) - 4) - (sizeof(struct pppoehdr) + 2))) {
1308 PPPOE_ADD_16(p, PPPOE_TAG_MAX_PAYLOAD)*(p)++ = (0x0120) / 256; *(p)++ = (0x0120) % 256;
1309 PPPOE_ADD_16(p, 2)*(p)++ = (2) / 256; *(p)++ = (2) % 256;
1310 PPPOE_ADD_16(p, (u_int16_t)sc->sc_sppp.pp_if.if_mtu)*(p)++ = ((u_int16_t)sc->sc_sppp.pp_if.if_data.ifi_mtu) / 256
; *(p)++ = ((u_int16_t)sc->sc_sppp.pp_if.if_data.ifi_mtu) %
256
;
1311 }
1312
1313#ifdef PPPOE_DEBUG
1314 if (p - mtod(m0, u_int8_t *)((u_int8_t *)((m0)->m_hdr.mh_data)) != len + PPPOE_HEADERLENsizeof(struct pppoehdr))
1315 panic("pppoe_send_padr: garbled output len, should be %ld, is %ld",
1316 (long)(len + PPPOE_HEADERLENsizeof(struct pppoehdr)), (long)(p - mtod(m0, u_int8_t *)((u_int8_t *)((m0)->m_hdr.mh_data))));
1317#endif
1318
1319 return (pppoe_output(sc, m0));
1320}
1321
1322/* Send a PADT packet. */
1323static int
1324pppoe_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((void *)0))
1334 return (EINVAL22);
1335
1336 m0 = pppoe_get_mbuf(PPPOE_HEADERLENsizeof(struct pppoehdr));
1337 if (m0 == NULL((void *)0)) {
1338 if_put(eth_if);
1339 return (ENOBUFS55);
1340 }
1341 m0->m_pkthdrM_dat.MH.MH_pkthdr.pf.prio = prio;
1342
1343 p = mtod(m0, u_int8_t *)((u_int8_t *)((m0)->m_hdr.mh_data));
1344 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0)*(p)++ = 0x11; *(p)++ = (0xA7); *(p)++ = (session) / 256; *(p
)++ = (session) % 256; *(p)++ = (0) / 256; *(p)++ = (0) % 256
;
1345
1346 memset(&dst, 0, sizeof(dst))__builtin_memset((&dst), (0), (sizeof(dst)));
1347 dst.sa_family = AF_UNSPEC0;
1348 eh = (struct ether_header *)&dst.sa_data;
1349 eh->ether_type = htons(ETHERTYPE_PPPOEDISC)(__uint16_t)(__builtin_constant_p(0x8863) ? (__uint16_t)(((__uint16_t
)(0x8863) & 0xffU) << 8 | ((__uint16_t)(0x8863) &
0xff00U) >> 8) : __swap16md(0x8863))
;
1350 memcpy(&eh->ether_dhost, dest, ETHER_ADDR_LEN)__builtin_memcpy((&eh->ether_dhost), (dest), (6));
1351
1352 m0->m_flagsm_hdr.mh_flags &= ~(M_BCAST0x0100|M_MCAST0x0200);
1353 /* encapsulated packet is forced into rdomain of physical interface */
1354 m0->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid = eth_if->if_rdomainif_data.ifi_rdomain;
1355
1356 ret = eth_if->if_output(eth_if, m0, &dst, NULL((void *)0));
1357 if_put(eth_if);
1358
1359 return (ret);
1360}
1361
1362
1363/* this-layer-start function */
1364static void
1365pppoe_tls(struct sppp *sp)
1366{
1367 struct pppoe_softc *sc = (void *)sp;
1368
1369 if (sc->sc_state != PPPOE_STATE_INITIAL0)
1370 return;
1371 pppoe_connect(sc);
1372}
1373
1374/* this-layer-finish function */
1375static void
1376pppoe_tlf(struct sppp *sp)
1377{
1378 struct pppoe_softc *sc = (void *)sp;
1379
1380 if (sc->sc_state < PPPOE_STATE_SESSION3)
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_CLOSING4;
1388 timeout_add_msec(&sc->sc_timeout, 20);
1389}
1390
1391static void
1392pppoe_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_SESSION3) {
1404 sppp_flush(&sc->sc_sppp.pp_if);
1405 return;
1406 }
1407
1408 while ((m = sppp_dequeue(ifp)) != NULL((void *)0)) {
1409 len = m->m_pkthdrM_dat.MH.MH_pkthdr.len;
1410 M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT)(m) = m_prepend((m), (sizeof(struct pppoehdr)), (0x0002));
1411 if (m == NULL((void *)0)) {
1412 ifp->if_oerrorsif_data.ifi_oerrors++;
1413 continue;
1414 }
1415 p = mtod(m, u_int8_t *)((u_int8_t *)((m)->m_hdr.mh_data));
1416 PPPOE_ADD_HEADER(p, 0, sc->sc_session, len)*(p)++ = 0x11; *(p)++ = (0); *(p)++ = (sc->sc_session) / 256
; *(p)++ = (sc->sc_session) % 256; *(p)++ = (len) / 256; *
(p)++ = (len) % 256
;
1417
1418#if NBPFILTER1 > 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(1 << 1));
1422#endif
1423
1424 pppoe_output(sc, m);
1425 }
1426}