ReactOS 0.4.15-dev-7953-g1f49173
ppp_oe.c
Go to the documentation of this file.
1/*****************************************************************************
2* ppp_oe.c - PPP Over Ethernet implementation for lwIP.
3*
4* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc.
5*
6* The authors hereby grant permission to use, copy, modify, distribute,
7* and license this software and its documentation for any purpose, provided
8* that existing copyright notices are retained in all copies and that this
9* notice and the following disclaimer are included verbatim in any
10* distributions. No written agreement, license, or royalty fee is required
11* for any of the authorized uses.
12*
13* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
14* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
17* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23*
24******************************************************************************
25* REVISION HISTORY
26*
27* 06-01-01 Marc Boucher <marc@mbsi.ca>
28* Ported to lwIP.
29*****************************************************************************/
30
31
32
33/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */
34
35/*-
36 * Copyright (c) 2002 The NetBSD Foundation, Inc.
37 * All rights reserved.
38 *
39 * This code is derived from software contributed to The NetBSD Foundation
40 * by Martin Husemann <martin@NetBSD.org>.
41 *
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution.
50 * 3. All advertising materials mentioning features or use of this software
51 * must display the following acknowledgement:
52 * This product includes software developed by the NetBSD
53 * Foundation, Inc. and its contributors.
54 * 4. Neither the name of The NetBSD Foundation nor the names of its
55 * contributors may be used to endorse or promote products derived
56 * from this software without specific prior written permission.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
59 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
60 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
61 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
62 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
63 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
64 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
65 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
66 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
67 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68 * POSSIBILITY OF SUCH DAMAGE.
69 */
70
71#include "lwip/opt.h"
72
73#if PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */
74
75#include "netif/ppp_oe.h"
76
77#include "ppp_impl.h"
78#include "pppdebug.h"
79
80#include "lwip/timers.h"
81#include "lwip/memp.h"
82
83#include <string.h>
84#include <stdio.h>
85
86
87/* Add a 16 bit unsigned value to a buffer pointed to by PTR */
88#define PPPOE_ADD_16(PTR, VAL) \
89 *(PTR)++ = (u8_t)((VAL) / 256); \
90 *(PTR)++ = (u8_t)((VAL) % 256)
91
92/* Add a complete PPPoE header to the buffer pointed to by PTR */
93#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \
94 *(PTR)++ = PPPOE_VERTYPE; \
95 *(PTR)++ = (CODE); \
96 PPPOE_ADD_16(PTR, SESS); \
97 PPPOE_ADD_16(PTR, LEN)
98
99#define PPPOE_DISC_TIMEOUT (5*1000) /* base for quick timeout calculation */
100#define PPPOE_SLOW_RETRY (60*1000) /* persistent retry interval */
101#define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */
102#define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */
103
104#ifdef PPPOE_SERVER
105#error "PPPOE_SERVER is not yet supported under lwIP!"
106/* from if_spppsubr.c */
107#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
108#endif
109
110#ifndef PPPOE_ERRORSTRING_LEN
111#define PPPOE_ERRORSTRING_LEN 64
112#endif
113static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN];
114
115
116/* input routines */
117static void pppoe_dispatch_disc_pkt(struct netif *, struct pbuf *);
118
119/* management routines */
120static int pppoe_do_disconnect(struct pppoe_softc *);
121static void pppoe_abort_connect(struct pppoe_softc *);
122static void pppoe_clear_softc(struct pppoe_softc *, const char *);
123
124/* internal timeout handling */
125static void pppoe_timeout(void *);
126
127/* sending actual protocol controll packets */
128static err_t pppoe_send_padi(struct pppoe_softc *);
129static err_t pppoe_send_padr(struct pppoe_softc *);
130#ifdef PPPOE_SERVER
131static err_t pppoe_send_pado(struct pppoe_softc *);
132static err_t pppoe_send_pads(struct pppoe_softc *);
133#endif
134static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *);
135
136/* internal helper functions */
137static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct netif *);
138static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct netif *);
139
141static struct pppoe_softc *pppoe_softc_list;
142
143err_t
144pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr)
145{
146 struct pppoe_softc *sc;
147
148 sc = (struct pppoe_softc *)memp_malloc(MEMP_PPPOE_IF);
149 if (sc == NULL) {
150 *scptr = NULL;
151 return ERR_MEM;
152 }
153 memset(sc, 0, sizeof(struct pppoe_softc));
154
155 /* changed to real address later */
156 MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
157
158 sc->sc_pd = pd;
159 sc->sc_linkStatusCB = linkStatusCB;
160 sc->sc_ethif = ethif;
161
162 /* put the new interface at the head of the list */
163 sc->next = pppoe_softc_list;
164 pppoe_softc_list = sc;
165
166 *scptr = sc;
167
168 return ERR_OK;
169}
170
171err_t
172pppoe_destroy(struct netif *ifp)
173{
174 struct pppoe_softc *sc, *prev = NULL;
175
176 for (sc = pppoe_softc_list; sc != NULL; prev = sc, sc = sc->next) {
177 if (sc->sc_ethif == ifp) {
178 break;
179 }
180 }
181
182 if(!(sc && (sc->sc_ethif == ifp))) {
183 return ERR_IF;
184 }
185
186 sys_untimeout(pppoe_timeout, sc);
187 if (prev == NULL) {
188 /* remove sc from the head of the list */
189 pppoe_softc_list = sc->next;
190 } else {
191 /* remove sc from the list */
192 prev->next = sc->next;
193 }
194
195#ifdef PPPOE_TODO
196 if (sc->sc_concentrator_name) {
197 mem_free(sc->sc_concentrator_name);
198 }
199 if (sc->sc_service_name) {
200 mem_free(sc->sc_service_name);
201 }
202#endif /* PPPOE_TODO */
203 memp_free(MEMP_PPPOE_IF, sc);
204
205 return ERR_OK;
206}
207
208/*
209 * Find the interface handling the specified session.
210 * Note: O(number of sessions open), this is a client-side only, mean
211 * and lean implementation, so number of open sessions typically should
212 * be 1.
213 */
214static struct pppoe_softc *
215pppoe_find_softc_by_session(u_int session, struct netif *rcvif)
216{
217 struct pppoe_softc *sc;
218
219 if (session == 0) {
220 return NULL;
221 }
222
223 for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) {
224 if (sc->sc_state == PPPOE_STATE_SESSION
225 && sc->sc_session == session) {
226 if (sc->sc_ethif == rcvif) {
227 return sc;
228 } else {
229 return NULL;
230 }
231 }
232 }
233 return NULL;
234}
235
236/* Check host unique token passed and return appropriate softc pointer,
237 * or NULL if token is bogus. */
238static struct pppoe_softc *
239pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif)
240{
241 struct pppoe_softc *sc, *t;
242
243 if (pppoe_softc_list == NULL) {
244 return NULL;
245 }
246
247 if (len != sizeof sc) {
248 return NULL;
249 }
250 MEMCPY(&t, token, len);
251
252 for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) {
253 if (sc == t) {
254 break;
255 }
256 }
257
258 if (sc == NULL) {
259 PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n"));
260 return NULL;
261 }
262
263 /* should be safe to access *sc now */
264 if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) {
265 printf("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n",
266 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state);
267 return NULL;
268 }
269 if (sc->sc_ethif != rcvif) {
270 printf("%c%c%"U16_F": wrong interface, not accepting host unique\n",
271 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
272 return NULL;
273 }
274 return sc;
275}
276
277static void
278pppoe_linkstatus_up(struct pppoe_softc *sc)
279{
280 sc->sc_linkStatusCB(sc->sc_pd, 1);
281}
282
283/* analyze and handle a single received packet while not in session state */
284static void
285pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb)
286{
287 u16_t tag, len;
288 u16_t session, plen;
289 struct pppoe_softc *sc;
290 const char *err_msg;
291 char devname[6];
292 u8_t *ac_cookie;
293 u16_t ac_cookie_len;
294#ifdef PPPOE_SERVER
295 u8_t *hunique;
296 size_t hunique_len;
297#endif
298 struct pppoehdr *ph;
299 struct pppoetag pt;
300 int off, err, errortag;
301 struct eth_hdr *ethhdr;
302
303 pb = pppSingleBuf(pb);
304
305 strcpy(devname, "pppoe"); /* as long as we don't know which instance */
306 err_msg = NULL;
307 errortag = 0;
308 if (pb->len < sizeof(*ethhdr)) {
309 goto done;
310 }
311 ethhdr = (struct eth_hdr *)pb->payload;
312 off = sizeof(*ethhdr);
313
314 ac_cookie = NULL;
315 ac_cookie_len = 0;
316#ifdef PPPOE_SERVER
317 hunique = NULL;
318 hunique_len = 0;
319#endif
320 session = 0;
321 if (pb->len - off < PPPOE_HEADERLEN) {
322 printf("pppoe: packet too short: %d\n", pb->len);
323 goto done;
324 }
325
326 ph = (struct pppoehdr *) (ethhdr + 1);
327 if (ph->vertype != PPPOE_VERTYPE) {
328 printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype);
329 goto done;
330 }
331 session = ntohs(ph->session);
332 plen = ntohs(ph->plen);
333 off += sizeof(*ph);
334
335 if (plen + off > pb->len) {
336 printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
337 pb->len - off, plen);
338 goto done;
339 }
340 if(pb->tot_len == pb->len) {
341 pb->tot_len = pb->len = (u16_t)off + plen; /* ignore trailing garbage */
342 }
343 tag = 0;
344 len = 0;
345 sc = NULL;
346 while (off + sizeof(pt) <= pb->len) {
347 MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt));
348 tag = ntohs(pt.tag);
349 len = ntohs(pt.len);
350 if (off + sizeof(pt) + len > pb->len) {
351 printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len);
352 goto done;
353 }
354 switch (tag) {
355 case PPPOE_TAG_EOL:
356 goto breakbreak;
357 case PPPOE_TAG_SNAME:
358 break; /* ignored */
359 case PPPOE_TAG_ACNAME:
360 break; /* ignored */
361 case PPPOE_TAG_HUNIQUE:
362 if (sc != NULL) {
363 break;
364 }
365#ifdef PPPOE_SERVER
366 hunique = (u8_t*)pb->payload + off + sizeof(pt);
367 hunique_len = len;
368#endif
369 sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif);
370 if (sc != NULL) {
371 snprintf(devname, sizeof(devname), "%c%c%"U16_F, sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
372 }
373 break;
374 case PPPOE_TAG_ACCOOKIE:
375 if (ac_cookie == NULL) {
376 ac_cookie = (u8_t*)pb->payload + off + sizeof(pt);
377 ac_cookie_len = len;
378 }
379 break;
380 case PPPOE_TAG_SNAME_ERR:
381 err_msg = "SERVICE NAME ERROR";
382 errortag = 1;
383 break;
384 case PPPOE_TAG_ACSYS_ERR:
385 err_msg = "AC SYSTEM ERROR";
386 errortag = 1;
387 break;
388 case PPPOE_TAG_GENERIC_ERR:
389 err_msg = "GENERIC ERROR";
390 errortag = 1;
391 break;
392 }
393 if (err_msg) {
394 if (errortag && len) {
395 u16_t error_len = LWIP_MIN(len, sizeof(pppoe_error_tmp)-1);
396 strncpy(pppoe_error_tmp, (char*)pb->payload + off + sizeof(pt), error_len);
397 pppoe_error_tmp[error_len-1] = '\0';
398 printf("%s: %s: %s\n", devname, err_msg, pppoe_error_tmp);
399 } else {
400 printf("%s: %s\n", devname, err_msg);
401 }
402 if (errortag) {
403 goto done;
404 }
405 }
406 off += sizeof(pt) + len;
407 }
408
409breakbreak:;
410 switch (ph->code) {
411 case PPPOE_CODE_PADI:
412#ifdef PPPOE_SERVER
413 /*
414 * got service name, concentrator name, and/or host unique.
415 * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP.
416 */
417 if (LIST_EMPTY(&pppoe_softc_list)) {
418 goto done;
419 }
420 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
421 if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) {
422 continue;
423 }
424 if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) {
425 continue;
426 }
427 if (sc->sc_state == PPPOE_STATE_INITIAL) {
428 break;
429 }
430 }
431 if (sc == NULL) {
432 /* printf("pppoe: free passive interface is not found\n"); */
433 goto done;
434 }
435 if (hunique) {
436 if (sc->sc_hunique) {
437 mem_free(sc->sc_hunique);
438 }
439 sc->sc_hunique = mem_malloc(hunique_len);
440 if (sc->sc_hunique == NULL) {
441 goto done;
442 }
443 sc->sc_hunique_len = hunique_len;
444 MEMCPY(sc->sc_hunique, hunique, hunique_len);
445 }
446 MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
447 sc->sc_state = PPPOE_STATE_PADO_SENT;
448 pppoe_send_pado(sc);
449 break;
450#endif /* PPPOE_SERVER */
451 case PPPOE_CODE_PADR:
452#ifdef PPPOE_SERVER
453 /*
454 * get sc from ac_cookie if IFF_PASSIVE
455 */
456 if (ac_cookie == NULL) {
457 /* be quiet if there is not a single pppoe instance */
458 printf("pppoe: received PADR but not includes ac_cookie\n");
459 goto done;
460 }
461 sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif);
462 if (sc == NULL) {
463 /* be quiet if there is not a single pppoe instance */
464 if (!LIST_EMPTY(&pppoe_softc_list)) {
465 printf("pppoe: received PADR but could not find request for it\n");
466 }
467 goto done;
468 }
469 if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
470 printf("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
471 goto done;
472 }
473 if (hunique) {
474 if (sc->sc_hunique) {
475 mem_free(sc->sc_hunique);
476 }
477 sc->sc_hunique = mem_malloc(hunique_len);
478 if (sc->sc_hunique == NULL) {
479 goto done;
480 }
481 sc->sc_hunique_len = hunique_len;
482 MEMCPY(sc->sc_hunique, hunique, hunique_len);
483 }
484 pppoe_send_pads(sc);
485 sc->sc_state = PPPOE_STATE_SESSION;
486 pppoe_linkstatus_up(sc); /* notify upper layers */
487 break;
488#else
489 /* ignore, we are no access concentrator */
490 goto done;
491#endif /* PPPOE_SERVER */
492 case PPPOE_CODE_PADO:
493 if (sc == NULL) {
494 /* be quiet if there is not a single pppoe instance */
495 if (pppoe_softc_list != NULL) {
496 printf("pppoe: received PADO but could not find request for it\n");
497 }
498 goto done;
499 }
500 if (sc->sc_state != PPPOE_STATE_PADI_SENT) {
501 printf("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
502 goto done;
503 }
504 if (ac_cookie) {
505 sc->sc_ac_cookie_len = ac_cookie_len;
506 MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
507 }
508 MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr));
509 sys_untimeout(pppoe_timeout, sc);
510 sc->sc_padr_retried = 0;
511 sc->sc_state = PPPOE_STATE_PADR_SENT;
512 if ((err = pppoe_send_padr(sc)) != 0) {
513 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
514 }
515 sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
516 break;
517 case PPPOE_CODE_PADS:
518 if (sc == NULL) {
519 goto done;
520 }
521 sc->sc_session = session;
522 sys_untimeout(pppoe_timeout, sc);
523 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session));
524 sc->sc_state = PPPOE_STATE_SESSION;
525 pppoe_linkstatus_up(sc); /* notify upper layers */
526 break;
527 case PPPOE_CODE_PADT:
528 if (sc == NULL) {
529 goto done;
530 }
531 pppoe_clear_softc(sc, "received PADT");
532 break;
533 default:
534 if(sc) {
535 printf("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n",
536 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num,
537 (u16_t)ph->code, session);
538 } else {
539 printf("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session);
540 }
541 break;
542 }
543
544done:
545 pbuf_free(pb);
546 return;
547}
548
549void
550pppoe_disc_input(struct netif *netif, struct pbuf *p)
551{
552 /* avoid error messages if there is not a single pppoe instance */
553 if (pppoe_softc_list != NULL) {
554 pppoe_dispatch_disc_pkt(netif, p);
555 } else {
556 pbuf_free(p);
557 }
558}
559
560void
561pppoe_data_input(struct netif *netif, struct pbuf *pb)
562{
563 u16_t session, plen;
564 struct pppoe_softc *sc;
565 struct pppoehdr *ph;
566#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
567 u8_t shost[ETHER_ADDR_LEN];
568#endif
569
570#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
571 MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost));
572#endif
573 if (pbuf_header(pb, -(int)sizeof(struct eth_hdr)) != 0) {
574 /* bail out */
575 PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header failed\n"));
576 LINK_STATS_INC(link.lenerr);
577 goto drop;
578 }
579
580 pb = pppSingleBuf (pb);
581
582 if (pb->len <= PPPOE_HEADERLEN) {
583 printf("pppoe (data): dropping too short packet: %d bytes\n", pb->len);
584 goto drop;
585 }
586
587 if (pb->len < sizeof(*ph)) {
588 printf("pppoe_data_input: could not get PPPoE header\n");
589 goto drop;
590 }
591 ph = (struct pppoehdr *)pb->payload;
592
593 if (ph->vertype != PPPOE_VERTYPE) {
594 printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype);
595 goto drop;
596 }
597 if (ph->code != 0) {
598 goto drop;
599 }
600
601 session = ntohs(ph->session);
602 sc = pppoe_find_softc_by_session(session, netif);
603 if (sc == NULL) {
604#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
605 printf("pppoe: input for unknown session 0x%x, sending PADT\n", session);
606 pppoe_send_padt(netif, session, shost);
607#endif
608 goto drop;
609 }
610
611 plen = ntohs(ph->plen);
612
613 if (pbuf_header(pb, -(int)(PPPOE_HEADERLEN)) != 0) {
614 /* bail out */
615 PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header PPPOE_HEADERLEN failed\n"));
616 LINK_STATS_INC(link.lenerr);
617 goto drop;
618 }
619
620 PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n",
621 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num,
622 pb->len, plen));
623
624 if (pb->len < plen) {
625 goto drop;
626 }
627
628 pppInProcOverEthernet(sc->sc_pd, pb);
629
630 return;
631
632drop:
633 pbuf_free(pb);
634}
635
636static err_t
637pppoe_output(struct pppoe_softc *sc, struct pbuf *pb)
638{
639 struct eth_hdr *ethhdr;
640 u16_t etype;
641 err_t res;
642
643 if (!sc->sc_ethif) {
644 pbuf_free(pb);
645 return ERR_IF;
646 }
647
648 ethhdr = (struct eth_hdr *)pb->payload;
649 etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC;
650 ethhdr->type = htons(etype);
651 MEMCPY(ethhdr->dest.addr, sc->sc_dest.addr, sizeof(ethhdr->dest.addr));
652 MEMCPY(ethhdr->src.addr, ((struct eth_addr *)sc->sc_ethif->hwaddr)->addr, sizeof(ethhdr->src.addr));
653
654 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n",
655 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype,
656 sc->sc_state, sc->sc_session,
657 sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5],
658 pb->tot_len));
659
660 res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb);
661
662 pbuf_free(pb);
663
664 return res;
665}
666
667static err_t
668pppoe_send_padi(struct pppoe_softc *sc)
669{
670 struct pbuf *pb;
671 u8_t *p;
672 int len;
673#ifdef PPPOE_TODO
674 int l1 = 0, l2 = 0; /* XXX: gcc */
675#endif /* PPPOE_TODO */
676
677 if (sc->sc_state >PPPOE_STATE_PADI_SENT) {
678 PPPDEBUG(LOG_ERR, ("ERROR: pppoe_send_padi in state %d", sc->sc_state));
679 }
680
681 /* calculate length of frame (excluding ethernet header + pppoe header) */
682 len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */
683#ifdef PPPOE_TODO
684 if (sc->sc_service_name != NULL) {
685 l1 = (int)strlen(sc->sc_service_name);
686 len += l1;
687 }
688 if (sc->sc_concentrator_name != NULL) {
689 l2 = (int)strlen(sc->sc_concentrator_name);
690 len += 2 + 2 + l2;
691 }
692#endif /* PPPOE_TODO */
693 LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
694 sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
695
696 /* allocate a buffer */
697 pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM);
698 if (!pb) {
699 return ERR_MEM;
700 }
701 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
702
703 p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
704 /* fill in pkt */
705 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len);
706 PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
707#ifdef PPPOE_TODO
708 if (sc->sc_service_name != NULL) {
709 PPPOE_ADD_16(p, l1);
710 MEMCPY(p, sc->sc_service_name, l1);
711 p += l1;
712 } else
713#endif /* PPPOE_TODO */
714 {
715 PPPOE_ADD_16(p, 0);
716 }
717#ifdef PPPOE_TODO
718 if (sc->sc_concentrator_name != NULL) {
719 PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
720 PPPOE_ADD_16(p, l2);
721 MEMCPY(p, sc->sc_concentrator_name, l2);
722 p += l2;
723 }
724#endif /* PPPOE_TODO */
725 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
726 PPPOE_ADD_16(p, sizeof(sc));
727 MEMCPY(p, &sc, sizeof sc);
728
729 /* send pkt */
730 return pppoe_output(sc, pb);
731}
732
733static void
734pppoe_timeout(void *arg)
735{
736 int retry_wait, err;
737 struct pppoe_softc *sc = (struct pppoe_softc*)arg;
738
739 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
740
741 switch (sc->sc_state) {
742 case PPPOE_STATE_PADI_SENT:
743 /*
744 * We have two basic ways of retrying:
745 * - Quick retry mode: try a few times in short sequence
746 * - Slow retry mode: we already had a connection successfully
747 * established and will try infinitely (without user
748 * intervention)
749 * We only enter slow retry mode if IFF_LINK1 (aka autodial)
750 * is not set.
751 */
752
753 /* initialize for quick retry mode */
754 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried);
755
756 sc->sc_padi_retried++;
757 if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) {
758#if 0
759 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) {
760 /* slow retry mode */
761 retry_wait = PPPOE_SLOW_RETRY;
762 } else
763#endif
764 {
765 pppoe_abort_connect(sc);
766 return;
767 }
768 }
769 if ((err = pppoe_send_padi(sc)) != 0) {
770 sc->sc_padi_retried--;
771 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
772 }
773 sys_timeout(retry_wait, pppoe_timeout, sc);
774 break;
775
776 case PPPOE_STATE_PADR_SENT:
777 sc->sc_padr_retried++;
778 if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) {
779 MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
780 sc->sc_state = PPPOE_STATE_PADI_SENT;
781 sc->sc_padr_retried = 0;
782 if ((err = pppoe_send_padi(sc)) != 0) {
783 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
784 }
785 sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc);
786 return;
787 }
788 if ((err = pppoe_send_padr(sc)) != 0) {
789 sc->sc_padr_retried--;
790 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
791 }
792 sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
793 break;
794 case PPPOE_STATE_CLOSING:
795 pppoe_do_disconnect(sc);
796 break;
797 default:
798 return; /* all done, work in peace */
799 }
800}
801
802/* Start a connection (i.e. initiate discovery phase) */
803int
804pppoe_connect(struct pppoe_softc *sc)
805{
806 int err;
807
808 if (sc->sc_state != PPPOE_STATE_INITIAL) {
809 return EBUSY;
810 }
811
812#ifdef PPPOE_SERVER
813 /* wait PADI if IFF_PASSIVE */
814 if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) {
815 return 0;
816 }
817#endif
818 /* save state, in case we fail to send PADI */
819 sc->sc_state = PPPOE_STATE_PADI_SENT;
820 sc->sc_padr_retried = 0;
821 err = pppoe_send_padi(sc);
822 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
823 sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc);
824 return err;
825}
826
827/* disconnect */
828void
829pppoe_disconnect(struct pppoe_softc *sc)
830{
831 if (sc->sc_state < PPPOE_STATE_SESSION) {
832 return;
833 }
834 /*
835 * Do not call pppoe_disconnect here, the upper layer state
836 * machine gets confused by this. We must return from this
837 * function and defer disconnecting to the timeout handler.
838 */
839 sc->sc_state = PPPOE_STATE_CLOSING;
840 sys_timeout(20, pppoe_timeout, sc);
841}
842
843static int
844pppoe_do_disconnect(struct pppoe_softc *sc)
845{
846 int err;
847
848 if (sc->sc_state < PPPOE_STATE_SESSION) {
849 err = EBUSY;
850 } else {
851 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
852 err = pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest);
853 }
854
855 /* cleanup softc */
856 sc->sc_state = PPPOE_STATE_INITIAL;
857 MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
858 sc->sc_ac_cookie_len = 0;
859#ifdef PPPOE_SERVER
860 if (sc->sc_hunique) {
861 mem_free(sc->sc_hunique);
862 sc->sc_hunique = NULL;
863 }
864 sc->sc_hunique_len = 0;
865#endif
866 sc->sc_session = 0;
867
868 sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */
869
870 return err;
871}
872
873/* Connection attempt aborted */
874static void
875pppoe_abort_connect(struct pppoe_softc *sc)
876{
877 printf("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
878 sc->sc_state = PPPOE_STATE_CLOSING;
879
880 sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */
881
882 /* clear connection state */
883 MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
884 sc->sc_state = PPPOE_STATE_INITIAL;
885}
886
887/* Send a PADR packet */
888static err_t
889pppoe_send_padr(struct pppoe_softc *sc)
890{
891 struct pbuf *pb;
892 u8_t *p;
893 size_t len;
894#ifdef PPPOE_TODO
895 size_t l1 = 0; /* XXX: gcc */
896#endif /* PPPOE_TODO */
897
898 if (sc->sc_state != PPPOE_STATE_PADR_SENT) {
899 return ERR_CONN;
900 }
901
902 len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */
903#ifdef PPPOE_TODO
904 if (sc->sc_service_name != NULL) { /* service name tag maybe empty */
905 l1 = strlen(sc->sc_service_name);
906 len += l1;
907 }
908#endif /* PPPOE_TODO */
909 if (sc->sc_ac_cookie_len > 0) {
910 len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */
911 }
912 LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
913 sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
914 pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM);
915 if (!pb) {
916 return ERR_MEM;
917 }
918 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
919 p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
920 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
921 PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
922#ifdef PPPOE_TODO
923 if (sc->sc_service_name != NULL) {
924 PPPOE_ADD_16(p, l1);
925 MEMCPY(p, sc->sc_service_name, l1);
926 p += l1;
927 } else
928#endif /* PPPOE_TODO */
929 {
930 PPPOE_ADD_16(p, 0);
931 }
932 if (sc->sc_ac_cookie_len > 0) {
933 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
934 PPPOE_ADD_16(p, sc->sc_ac_cookie_len);
935 MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
936 p += sc->sc_ac_cookie_len;
937 }
938 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
939 PPPOE_ADD_16(p, sizeof(sc));
940 MEMCPY(p, &sc, sizeof sc);
941
942 return pppoe_output(sc, pb);
943}
944
945/* send a PADT packet */
946static err_t
947pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest)
948{
949 struct pbuf *pb;
950 struct eth_hdr *ethhdr;
951 err_t res;
952 u8_t *p;
953
954 pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN, PBUF_RAM);
955 if (!pb) {
956 return ERR_MEM;
957 }
958 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
959
960 ethhdr = (struct eth_hdr *)pb->payload;
961 ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC);
962 MEMCPY(ethhdr->dest.addr, dest, sizeof(ethhdr->dest.addr));
963 MEMCPY(ethhdr->src.addr, ((struct eth_addr *)outgoing_if->hwaddr)->addr, sizeof(ethhdr->src.addr));
964
965 p = (u8_t*)(ethhdr + 1);
966 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0);
967
968 res = outgoing_if->linkoutput(outgoing_if, pb);
969
970 pbuf_free(pb);
971
972 return res;
973}
974
975#ifdef PPPOE_SERVER
976static err_t
977pppoe_send_pado(struct pppoe_softc *sc)
978{
979 struct pbuf *pb;
980 u8_t *p;
981 size_t len;
982
983 if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
984 return ERR_CONN;
985 }
986
987 /* calc length */
988 len = 0;
989 /* include ac_cookie */
990 len += 2 + 2 + sizeof(sc);
991 /* include hunique */
992 len += 2 + 2 + sc->sc_hunique_len;
993 pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM);
994 if (!pb) {
995 return ERR_MEM;
996 }
997 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
998 p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
999 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
1000 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
1001 PPPOE_ADD_16(p, sizeof(sc));
1002 MEMCPY(p, &sc, sizeof(sc));
1003 p += sizeof(sc);
1004 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1005 PPPOE_ADD_16(p, sc->sc_hunique_len);
1006 MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len);
1007 return pppoe_output(sc, pb);
1008}
1009
1010static err_t
1011pppoe_send_pads(struct pppoe_softc *sc)
1012{
1013 struct pbuf *pb;
1014 u8_t *p;
1015 size_t len, l1 = 0; /* XXX: gcc */
1016
1017 if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
1018 return ERR_CONN;
1019 }
1020
1021 sc->sc_session = mono_time.tv_sec % 0xff + 1;
1022 /* calc length */
1023 len = 0;
1024 /* include hunique */
1025 len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/
1026 if (sc->sc_service_name != NULL) { /* service name tag maybe empty */
1027 l1 = strlen(sc->sc_service_name);
1028 len += l1;
1029 }
1030 pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM);
1031 if (!pb) {
1032 return ERR_MEM;
1033 }
1034 LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
1035 p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
1036 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len);
1037 PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
1038 if (sc->sc_service_name != NULL) {
1039 PPPOE_ADD_16(p, l1);
1040 MEMCPY(p, sc->sc_service_name, l1);
1041 p += l1;
1042 } else {
1043 PPPOE_ADD_16(p, 0);
1044 }
1045 PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
1046 PPPOE_ADD_16(p, sc->sc_hunique_len);
1047 MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len);
1048 return pppoe_output(sc, pb);
1049}
1050#endif
1051
1052err_t
1053pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb)
1054{
1055 u8_t *p;
1056 size_t len;
1057
1058 /* are we ready to process data yet? */
1059 if (sc->sc_state < PPPOE_STATE_SESSION) {
1060 /*sppp_flush(&sc->sc_sppp.pp_if);*/
1061 pbuf_free(pb);
1062 return ERR_CONN;
1063 }
1064
1065 len = pb->tot_len;
1066
1067 /* make room for Ethernet header - should not fail */
1068 if (pbuf_header(pb, sizeof(struct eth_hdr) + PPPOE_HEADERLEN) != 0) {
1069 /* bail out */
1070 PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
1071 LINK_STATS_INC(link.lenerr);
1072 pbuf_free(pb);
1073 return ERR_BUF;
1074 }
1075
1076 p = (u8_t*)pb->payload + sizeof(struct eth_hdr);
1077 PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
1078
1079 return pppoe_output(sc, pb);
1080}
1081
1082#if 0 /*def PFIL_HOOKS*/
1083static int
1084pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir)
1085{
1086 struct pppoe_softc *sc;
1087 int s;
1088
1089 if (mp != (struct pbuf **)PFIL_IFNET_DETACH) {
1090 return 0;
1091 }
1092
1093 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
1094 if (sc->sc_ethif != ifp) {
1095 continue;
1096 }
1097 if (sc->sc_sppp.pp_if.if_flags & IFF_UP) {
1098 sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
1099 printf("%c%c%"U16_F": ethernet interface detached, going down\n",
1100 sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
1101 }
1102 sc->sc_ethif = NULL;
1103 pppoe_clear_softc(sc, "ethernet interface detached");
1104 }
1105
1106 return 0;
1107}
1108#endif
1109
1110static void
1111pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
1112{
1114
1115 /* stop timer */
1116 sys_untimeout(pppoe_timeout, sc);
1117 PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message));
1118
1119 /* fix our state */
1120 sc->sc_state = PPPOE_STATE_INITIAL;
1121
1122 /* notify upper layers */
1123 sc->sc_linkStatusCB(sc->sc_pd, 0);
1124
1125 /* clean up softc */
1126 MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
1127 sc->sc_ac_cookie_len = 0;
1128 sc->sc_session = 0;
1129}
1130
1131#endif /* PPPOE_SUPPORT */
1132
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define EBUSY
Definition: acclib.h:87
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
unsigned int dir
Definition: maze.c:112
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
const WCHAR * link
Definition: db.cpp:997
#define PP_HTONS(x)
Definition: def.h:88
#define LWIP_MIN(x, y)
Definition: def.h:44
#define ETHER_ADDR_LEN
Definition: dhcpd.h:51
UINT32 u_int
Definition: types.h:82
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define pt(x, y)
Definition: drawing.c:79
#define X16_F
Definition: cc.h:38
#define U16_F
Definition: cc.h:36
unsigned char u8_t
Definition: cc.h:23
unsigned short u16_t
Definition: cc.h:24
void * mem_malloc(mem_size_t size)
Definition: mem.c:494
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
#define ERR_MEM
Definition: err.h:53
#define ERR_CONN
Definition: err.h:68
#define ERR_OK
Definition: err.h:52
#define ERR_BUF
Definition: err.h:54
s8_t err_t
Definition: err.h:47
#define ERR_IF
Definition: err.h:72
#define printf
Definition: freeldr.h:97
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble t
Definition: gl.h:2047
GLuint res
Definition: glext.h:9613
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
#define up(mutex)
Definition: glue.h:30
if(dx< 0)
Definition: linetemp.h:194
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
void * memp_malloc(memp_t type)
Definition: memp.c:390
void memp_free(memp_t type, void *mem)
Definition: memp.c:435
#define htons(x)
Definition: module.h:215
#define ntohs(x)
Definition: module.h:210
static char * dest
Definition: rtl.c:135
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:511
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:207
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
@ PBUF_RAM
Definition: pbuf.h:58
@ PBUF_LINK
Definition: pbuf.h:53
#define PPPDEBUG(a, b)
Definition: pppdebug.h:69
#define err(...)
#define memset(x, y, z)
Definition: compat.h:39
#define LINK_STATS_INC(x)
Definition: stats.h:227
struct define * next
Definition: compiler.c:65
char * name
Definition: compiler.c:66
Definition: tftpd.h:60
Definition: netif.h:136
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:190
netif_linkoutput_fn linkoutput
Definition: netif.h:155
struct netif * next
Definition: netif.h:138
Definition: pbuf.h:79
u16_t tot_len
Definition: pbuf.h:93
u16_t len
Definition: pbuf.h:96
void * payload
Definition: pbuf.h:84
Definition: ecma_167.h:138
#define LIST_FOREACH(var, head, field)
Definition: queue.h:189
#define LIST_EMPTY(head)
Definition: queue.h:186
#define LOG_DEBUG
Definition: syslog.h:52
#define LOG_ERR
Definition: syslog.h:48
void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
void sys_untimeout(sys_timeout_handler handler, void *arg)
#define snprintf
Definition: wintirpc.h:48
#define IFF_UP
Definition: ws2ipdef.h:21
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList