ReactOS  0.4.15-dev-1207-g698a8e6
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
113 static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN];
114 
115 
116 /* input routines */
117 static void pppoe_dispatch_disc_pkt(struct netif *, struct pbuf *);
118 
119 /* management routines */
120 static int pppoe_do_disconnect(struct pppoe_softc *);
121 static void pppoe_abort_connect(struct pppoe_softc *);
122 static void pppoe_clear_softc(struct pppoe_softc *, const char *);
123 
124 /* internal timeout handling */
125 static void pppoe_timeout(void *);
126 
127 /* sending actual protocol controll packets */
128 static err_t pppoe_send_padi(struct pppoe_softc *);
129 static err_t pppoe_send_padr(struct pppoe_softc *);
130 #ifdef PPPOE_SERVER
131 static err_t pppoe_send_pado(struct pppoe_softc *);
132 static err_t pppoe_send_pads(struct pppoe_softc *);
133 #endif
134 static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *);
135 
136 /* internal helper functions */
137 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct netif *);
138 static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct netif *);
139 
141 static struct pppoe_softc *pppoe_softc_list;
142 
143 err_t
144 pppoe_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 
171 err_t
172 pppoe_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  */
214 static struct pppoe_softc *
215 pppoe_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. */
238 static struct pppoe_softc *
239 pppoe_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 
277 static void
278 pppoe_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 */
284 static void
285 pppoe_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 
409 breakbreak:;
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 
544 done:
545  pbuf_free(pb);
546  return;
547 }
548 
549 void
550 pppoe_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 
560 void
561 pppoe_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 
632 drop:
633  pbuf_free(pb);
634 }
635 
636 static err_t
637 pppoe_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 
667 static err_t
668 pppoe_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 
733 static void
734 pppoe_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) */
803 int
804 pppoe_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 */
828 void
829 pppoe_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 
843 static int
844 pppoe_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 */
874 static void
875 pppoe_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 */
888 static err_t
889 pppoe_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 */
946 static err_t
947 pppoe_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
976 static err_t
977 pppoe_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 
1010 static err_t
1011 pppoe_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 
1052 err_t
1053 pppoe_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*/
1083 static int
1084 pppoe_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 
1110 static void
1111 pppoe_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 
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:190
#define ERR_CONN
Definition: err.h:68
u16_t tot_len
Definition: pbuf.h:93
Definition: tftpd.h:59
#define LIST_FOREACH(var, head, field)
Definition: queue.h:189
#define PPPDEBUG(a, b)
Definition: pppdebug.h:69
u16_t len
Definition: pbuf.h:96
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define pt(x, y)
Definition: drawing.c:79
#define IFF_UP
Definition: ws2ipdef.h:21
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
Definition: arc.h:37
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:511
GLdouble GLdouble t
Definition: gl.h:2047
#define snprintf
Definition: wintirpc.h:48
Definition: ecma_167.h:138
void * mem_malloc(mem_size_t size)
Definition: mem.c:494
#define LOG_DEBUG
Definition: syslog.h:52
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
#define ntohs(x)
Definition: module.h:208
void memp_free(memp_t type, void *mem)
Definition: memp.c:435
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:207
Definition: pbuf.h:58
#define up(mutex)
Definition: glue.h:30
Definition: pbuf.h:53
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 LWIP_MIN(x, y)
Definition: def.h:44
smooth NULL
Definition: ftsmooth.c:416
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
s8_t err_t
Definition: err.h:47
#define PP_HTONS(x)
Definition: def.h:88
unsigned int dir
Definition: maze.c:112
#define U16_F
Definition: cc.h:36
#define ERR_OK
Definition: err.h:52
struct netif * next
Definition: netif.h:138
if(!(yy_init))
Definition: macro.lex.yy.c:714
Definition: pbuf.h:79
void sys_untimeout(sys_timeout_handler handler, void *arg)
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
#define LINK_STATS_INC(x)
Definition: stats.h:227
#define X16_F
Definition: cc.h:38
char * name
Definition: compiler.c:66
Definition: netif.h:136
void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
#define LOG_ERR
Definition: syslog.h:48
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
#define err(...)
#define LIST_EMPTY(head)
Definition: queue.h:186
UINT32 u_int
Definition: types.h:82
#define ERR_MEM
Definition: fontsub.h:52
#define ERR_BUF
Definition: err.h:54
unsigned char u8_t
Definition: cc.h:23
void * payload
Definition: pbuf.h:84
GLuint res
Definition: glext.h:9613
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define mem_free(ptr, bsize)
Definition: types.h:124
static char * dest
Definition: rtl.c:135
unsigned short u16_t
Definition: cc.h:24
const WCHAR * link
Definition: db.cpp:989
#define ERR_IF
Definition: err.h:72
void * memp_malloc(memp_t type)
Definition: memp.c:390
#define ETHER_ADDR_LEN
Definition: dhcpd.h:51
GLfloat GLfloat p
Definition: glext.h:8902
#define htons(x)
Definition: module.h:213
#define memset(x, y, z)
Definition: compat.h:39
netif_linkoutput_fn linkoutput
Definition: netif.h:155
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
#define printf
Definition: config.h:203
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
off
Definition: i386-dis.c:3909
char * tag
Definition: main.c:59