BadVPN – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /***************************************************************************** |
2 | * ppp.c - Network Point to Point Protocol program file. |
||
3 | * |
||
4 | * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. |
||
5 | * portions Copyright (c) 1997 by Global Election Systems Inc. |
||
6 | * |
||
7 | * The authors hereby grant permission to use, copy, modify, distribute, |
||
8 | * and license this software and its documentation for any purpose, provided |
||
9 | * that existing copyright notices are retained in all copies and that this |
||
10 | * notice and the following disclaimer are included verbatim in any |
||
11 | * distributions. No written agreement, license, or royalty fee is required |
||
12 | * for any of the authorized uses. |
||
13 | * |
||
14 | * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR |
||
15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||
16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
||
17 | * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||
20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||
21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
24 | * |
||
25 | ****************************************************************************** |
||
26 | * REVISION HISTORY |
||
27 | * |
||
28 | * 03-01-01 Marc Boucher <marc@mbsi.ca> |
||
29 | * Ported to lwIP. |
||
30 | * 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc. |
||
31 | * Original. |
||
32 | *****************************************************************************/ |
||
33 | |||
34 | /* |
||
35 | * ppp_defs.h - PPP definitions. |
||
36 | * |
||
37 | * if_pppvar.h - private structures and declarations for PPP. |
||
38 | * |
||
39 | * Copyright (c) 1994 The Australian National University. |
||
40 | * All rights reserved. |
||
41 | * |
||
42 | * Permission to use, copy, modify, and distribute this software and its |
||
43 | * documentation is hereby granted, provided that the above copyright |
||
44 | * notice appears in all copies. This software is provided without any |
||
45 | * warranty, express or implied. The Australian National University |
||
46 | * makes no representations about the suitability of this software for |
||
47 | * any purpose. |
||
48 | * |
||
49 | * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY |
||
50 | * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
||
51 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF |
||
52 | * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY |
||
53 | * OF SUCH DAMAGE. |
||
54 | * |
||
55 | * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
||
56 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
||
57 | * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
||
58 | * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO |
||
59 | * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, |
||
60 | * OR MODIFICATIONS. |
||
61 | */ |
||
62 | |||
63 | /* |
||
64 | * if_ppp.h - Point-to-Point Protocol definitions. |
||
65 | * |
||
66 | * Copyright (c) 1989 Carnegie Mellon University. |
||
67 | * All rights reserved. |
||
68 | * |
||
69 | * Redistribution and use in source and binary forms are permitted |
||
70 | * provided that the above copyright notice and this paragraph are |
||
71 | * duplicated in all such forms and that any documentation, |
||
72 | * advertising materials, and other materials related to such |
||
73 | * distribution and use acknowledge that the software was developed |
||
74 | * by Carnegie Mellon University. The name of the |
||
75 | * University may not be used to endorse or promote products derived |
||
76 | * from this software without specific prior written permission. |
||
77 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
||
78 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
||
79 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
||
80 | */ |
||
81 | |||
82 | /** |
||
83 | * @defgroup ppp PPP |
||
84 | * @ingroup netifs |
||
85 | * @verbinclude "ppp.txt" |
||
86 | */ |
||
87 | |||
88 | #include "netif/ppp/ppp_opts.h" |
||
89 | #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ |
||
90 | |||
91 | #include "lwip/pbuf.h" |
||
92 | #include "lwip/stats.h" |
||
93 | #include "lwip/sys.h" |
||
94 | #include "lwip/tcpip.h" |
||
95 | #include "lwip/api.h" |
||
96 | #include "lwip/snmp.h" |
||
97 | #include "lwip/ip4.h" /* for ip4_input() */ |
||
98 | #if PPP_IPV6_SUPPORT |
||
99 | #include "lwip/ip6.h" /* for ip6_input() */ |
||
100 | #endif /* PPP_IPV6_SUPPORT */ |
||
101 | #include "lwip/dns.h" |
||
102 | |||
103 | #include "netif/ppp/ppp_impl.h" |
||
104 | #include "netif/ppp/pppos.h" |
||
105 | |||
106 | #include "netif/ppp/fsm.h" |
||
107 | #include "netif/ppp/lcp.h" |
||
108 | #include "netif/ppp/magic.h" |
||
109 | |||
110 | #if PAP_SUPPORT |
||
111 | #include "netif/ppp/upap.h" |
||
112 | #endif /* PAP_SUPPORT */ |
||
113 | #if CHAP_SUPPORT |
||
114 | #include "netif/ppp/chap-new.h" |
||
115 | #endif /* CHAP_SUPPORT */ |
||
116 | #if EAP_SUPPORT |
||
117 | #include "netif/ppp/eap.h" |
||
118 | #endif /* EAP_SUPPORT */ |
||
119 | #if CCP_SUPPORT |
||
120 | #include "netif/ppp/ccp.h" |
||
121 | #endif /* CCP_SUPPORT */ |
||
122 | #if MPPE_SUPPORT |
||
123 | #include "netif/ppp/mppe.h" |
||
124 | #endif /* MPPE_SUPPORT */ |
||
125 | #if ECP_SUPPORT |
||
126 | #include "netif/ppp/ecp.h" |
||
127 | #endif /* EAP_SUPPORT */ |
||
128 | #if VJ_SUPPORT |
||
129 | #include "netif/ppp/vj.h" |
||
130 | #endif /* VJ_SUPPORT */ |
||
131 | #if PPP_IPV4_SUPPORT |
||
132 | #include "netif/ppp/ipcp.h" |
||
133 | #endif /* PPP_IPV4_SUPPORT */ |
||
134 | #if PPP_IPV6_SUPPORT |
||
135 | #include "netif/ppp/ipv6cp.h" |
||
136 | #endif /* PPP_IPV6_SUPPORT */ |
||
137 | |||
138 | /*************************/ |
||
139 | /*** LOCAL DEFINITIONS ***/ |
||
140 | /*************************/ |
||
141 | |||
142 | /* Memory pools */ |
||
143 | #if PPPOS_SUPPORT |
||
144 | LWIP_MEMPOOL_PROTOTYPE(PPPOS_PCB); |
||
145 | #endif |
||
146 | #if PPPOE_SUPPORT |
||
147 | LWIP_MEMPOOL_PROTOTYPE(PPPOE_IF); |
||
148 | #endif |
||
149 | #if PPPOL2TP_SUPPORT |
||
150 | LWIP_MEMPOOL_PROTOTYPE(PPPOL2TP_PCB); |
||
151 | #endif |
||
152 | #if LWIP_PPP_API && LWIP_MPU_COMPATIBLE |
||
153 | LWIP_MEMPOOL_PROTOTYPE(PPPAPI_MSG); |
||
154 | #endif |
||
155 | LWIP_MEMPOOL_DECLARE(PPP_PCB, MEMP_NUM_PPP_PCB, sizeof(ppp_pcb), "PPP_PCB") |
||
156 | |||
157 | /* FIXME: add stats per PPP session */ |
||
158 | #if PPP_STATS_SUPPORT |
||
159 | static struct timeval start_time; /* Time when link was started. */ |
||
160 | static struct pppd_stats old_link_stats; |
||
161 | struct pppd_stats link_stats; |
||
162 | unsigned link_connect_time; |
||
163 | int link_stats_valid; |
||
164 | #endif /* PPP_STATS_SUPPORT */ |
||
165 | |||
166 | /* |
||
167 | * PPP Data Link Layer "protocol" table. |
||
168 | * One entry per supported protocol. |
||
169 | * The last entry must be NULL. |
||
170 | */ |
||
171 | const struct protent* const protocols[] = { |
||
172 | &lcp_protent, |
||
173 | #if PAP_SUPPORT |
||
174 | &pap_protent, |
||
175 | #endif /* PAP_SUPPORT */ |
||
176 | #if CHAP_SUPPORT |
||
177 | &chap_protent, |
||
178 | #endif /* CHAP_SUPPORT */ |
||
179 | #if CBCP_SUPPORT |
||
180 | &cbcp_protent, |
||
181 | #endif /* CBCP_SUPPORT */ |
||
182 | #if PPP_IPV4_SUPPORT |
||
183 | &ipcp_protent, |
||
184 | #endif /* PPP_IPV4_SUPPORT */ |
||
185 | #if PPP_IPV6_SUPPORT |
||
186 | &ipv6cp_protent, |
||
187 | #endif /* PPP_IPV6_SUPPORT */ |
||
188 | #if CCP_SUPPORT |
||
189 | &ccp_protent, |
||
190 | #endif /* CCP_SUPPORT */ |
||
191 | #if ECP_SUPPORT |
||
192 | &ecp_protent, |
||
193 | #endif /* ECP_SUPPORT */ |
||
194 | #ifdef AT_CHANGE |
||
195 | &atcp_protent, |
||
196 | #endif /* AT_CHANGE */ |
||
197 | #if EAP_SUPPORT |
||
198 | &eap_protent, |
||
199 | #endif /* EAP_SUPPORT */ |
||
200 | NULL |
||
201 | }; |
||
202 | |||
203 | /* Prototypes for procedures local to this file. */ |
||
204 | static void ppp_do_connect(void *arg); |
||
205 | static err_t ppp_netif_init_cb(struct netif *netif); |
||
206 | #if LWIP_IPV4 |
||
207 | static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr); |
||
208 | #endif /* LWIP_IPV4 */ |
||
209 | #if PPP_IPV6_SUPPORT |
||
210 | static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr); |
||
211 | #endif /* PPP_IPV6_SUPPORT */ |
||
212 | static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol); |
||
213 | |||
214 | /***********************************/ |
||
215 | /*** PUBLIC FUNCTION DEFINITIONS ***/ |
||
216 | /***********************************/ |
||
217 | #if PPP_AUTH_SUPPORT |
||
218 | void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) { |
||
219 | #if PAP_SUPPORT |
||
220 | pcb->settings.refuse_pap = !(authtype & PPPAUTHTYPE_PAP); |
||
221 | #endif /* PAP_SUPPORT */ |
||
222 | #if CHAP_SUPPORT |
||
223 | pcb->settings.refuse_chap = !(authtype & PPPAUTHTYPE_CHAP); |
||
224 | #if MSCHAP_SUPPORT |
||
225 | pcb->settings.refuse_mschap = !(authtype & PPPAUTHTYPE_MSCHAP); |
||
226 | pcb->settings.refuse_mschap_v2 = !(authtype & PPPAUTHTYPE_MSCHAP_V2); |
||
227 | #endif /* MSCHAP_SUPPORT */ |
||
228 | #endif /* CHAP_SUPPORT */ |
||
229 | #if EAP_SUPPORT |
||
230 | pcb->settings.refuse_eap = !(authtype & PPPAUTHTYPE_EAP); |
||
231 | #endif /* EAP_SUPPORT */ |
||
232 | pcb->settings.user = user; |
||
233 | pcb->settings.passwd = passwd; |
||
234 | } |
||
235 | #endif /* PPP_AUTH_SUPPORT */ |
||
236 | |||
237 | #if MPPE_SUPPORT |
||
238 | /* Set MPPE configuration */ |
||
239 | void ppp_set_mppe(ppp_pcb *pcb, u8_t flags) { |
||
240 | if (flags == PPP_MPPE_DISABLE) { |
||
241 | pcb->settings.require_mppe = 0; |
||
242 | return; |
||
243 | } |
||
244 | |||
245 | pcb->settings.require_mppe = 1; |
||
246 | pcb->settings.refuse_mppe_stateful = !(flags & PPP_MPPE_ALLOW_STATEFUL); |
||
247 | pcb->settings.refuse_mppe_40 = !!(flags & PPP_MPPE_REFUSE_40); |
||
248 | pcb->settings.refuse_mppe_128 = !!(flags & PPP_MPPE_REFUSE_128); |
||
249 | } |
||
250 | #endif /* MPPE_SUPPORT */ |
||
251 | |||
252 | #if PPP_NOTIFY_PHASE |
||
253 | void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) { |
||
254 | pcb->notify_phase_cb = notify_phase_cb; |
||
255 | notify_phase_cb(pcb, pcb->phase, pcb->ctx_cb); |
||
256 | } |
||
257 | #endif /* PPP_NOTIFY_PHASE */ |
||
258 | |||
259 | /* |
||
260 | * Initiate a PPP connection. |
||
261 | * |
||
262 | * This can only be called if PPP is in the dead phase. |
||
263 | * |
||
264 | * Holdoff is the time to wait (in seconds) before initiating |
||
265 | * the connection. |
||
266 | * |
||
267 | * If this port connects to a modem, the modem connection must be |
||
268 | * established before calling this. |
||
269 | */ |
||
270 | err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff) { |
||
271 | if (pcb->phase != PPP_PHASE_DEAD) { |
||
272 | return ERR_ALREADY; |
||
273 | } |
||
274 | |||
275 | PPPDEBUG(LOG_DEBUG, ("ppp_connect[%d]: holdoff=%d\n", pcb->netif->num, holdoff)); |
||
276 | |||
277 | if (holdoff == 0) { |
||
278 | ppp_do_connect(pcb); |
||
279 | return ERR_OK; |
||
280 | } |
||
281 | |||
282 | new_phase(pcb, PPP_PHASE_HOLDOFF); |
||
283 | sys_timeout((u32_t)(holdoff*1000), ppp_do_connect, pcb); |
||
284 | return ERR_OK; |
||
285 | } |
||
286 | |||
287 | #if PPP_SERVER |
||
288 | /* |
||
289 | * Listen for an incoming PPP connection. |
||
290 | * |
||
291 | * This can only be called if PPP is in the dead phase. |
||
292 | * |
||
293 | * If this port connects to a modem, the modem connection must be |
||
294 | * established before calling this. |
||
295 | */ |
||
296 | err_t ppp_listen(ppp_pcb *pcb) { |
||
297 | if (pcb->phase != PPP_PHASE_DEAD) { |
||
298 | return ERR_ALREADY; |
||
299 | } |
||
300 | |||
301 | PPPDEBUG(LOG_DEBUG, ("ppp_listen[%d]\n", pcb->netif->num)); |
||
302 | |||
303 | if (pcb->link_cb->listen) { |
||
304 | new_phase(pcb, PPP_PHASE_INITIALIZE); |
||
305 | pcb->link_cb->listen(pcb, pcb->link_ctx_cb); |
||
306 | return ERR_OK; |
||
307 | } |
||
308 | return ERR_IF; |
||
309 | } |
||
310 | #endif /* PPP_SERVER */ |
||
311 | |||
312 | /* |
||
313 | * Initiate the end of a PPP connection. |
||
314 | * Any outstanding packets in the queues are dropped. |
||
315 | * |
||
316 | * Setting nocarrier to 1 close the PPP connection without initiating the |
||
317 | * shutdown procedure. Always using nocarrier = 0 is still recommended, |
||
318 | * this is going to take a little longer time if your link is down, but |
||
319 | * is a safer choice for the PPP state machine. |
||
320 | * |
||
321 | * Return 0 on success, an error code on failure. |
||
322 | */ |
||
323 | err_t |
||
324 | ppp_close(ppp_pcb *pcb, u8_t nocarrier) |
||
325 | { |
||
326 | pcb->err_code = PPPERR_USER; |
||
327 | |||
328 | /* holdoff phase, cancel the reconnection */ |
||
329 | if (pcb->phase == PPP_PHASE_HOLDOFF) { |
||
330 | sys_untimeout(ppp_do_connect, pcb); |
||
331 | new_phase(pcb, PPP_PHASE_DEAD); |
||
332 | } |
||
333 | |||
334 | /* dead phase, nothing to do, call the status callback to be consistent */ |
||
335 | if (pcb->phase == PPP_PHASE_DEAD) { |
||
336 | pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); |
||
337 | return ERR_OK; |
||
338 | } |
||
339 | |||
340 | /* Already terminating, nothing to do */ |
||
341 | if (pcb->phase >= PPP_PHASE_TERMINATE) { |
||
342 | return ERR_INPROGRESS; |
||
343 | } |
||
344 | |||
345 | /* LCP not open, close link protocol */ |
||
346 | if (pcb->phase < PPP_PHASE_ESTABLISH) { |
||
347 | new_phase(pcb, PPP_PHASE_DISCONNECT); |
||
348 | ppp_link_terminated(pcb); |
||
349 | return ERR_OK; |
||
350 | } |
||
351 | |||
352 | /* |
||
353 | * Only accept carrier lost signal on the stable running phase in order |
||
354 | * to prevent changing the PPP phase FSM in transition phases. |
||
355 | * |
||
356 | * Always using nocarrier = 0 is still recommended, this is going to |
||
357 | * take a little longer time, but is a safer choice from FSM point of view. |
||
358 | */ |
||
359 | if (nocarrier && pcb->phase == PPP_PHASE_RUNNING) { |
||
360 | PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: carrier lost -> lcp_lowerdown\n", pcb->netif->num)); |
||
361 | lcp_lowerdown(pcb); |
||
362 | /* forced link termination, this will force link protocol to disconnect. */ |
||
363 | link_terminated(pcb); |
||
364 | return ERR_OK; |
||
365 | } |
||
366 | |||
367 | /* Disconnect */ |
||
368 | PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: kill_link -> lcp_close\n", pcb->netif->num)); |
||
369 | /* LCP soft close request. */ |
||
370 | lcp_close(pcb, "User request"); |
||
371 | return ERR_OK; |
||
372 | } |
||
373 | |||
374 | /* |
||
375 | * Release the control block. |
||
376 | * |
||
377 | * This can only be called if PPP is in the dead phase. |
||
378 | * |
||
379 | * You must use ppp_close() before if you wish to terminate |
||
380 | * an established PPP session. |
||
381 | * |
||
382 | * Return 0 on success, an error code on failure. |
||
383 | */ |
||
384 | err_t ppp_free(ppp_pcb *pcb) { |
||
385 | err_t err; |
||
386 | if (pcb->phase != PPP_PHASE_DEAD) { |
||
387 | return ERR_CONN; |
||
388 | } |
||
389 | |||
390 | PPPDEBUG(LOG_DEBUG, ("ppp_free[%d]\n", pcb->netif->num)); |
||
391 | |||
392 | netif_remove(pcb->netif); |
||
393 | |||
394 | err = pcb->link_cb->free(pcb, pcb->link_ctx_cb); |
||
395 | |||
396 | LWIP_MEMPOOL_FREE(PPP_PCB, pcb); |
||
397 | return err; |
||
398 | } |
||
399 | |||
400 | /* Get and set parameters for the given connection. |
||
401 | * Return 0 on success, an error code on failure. */ |
||
402 | err_t |
||
403 | ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg) |
||
404 | { |
||
405 | if (pcb == NULL) { |
||
406 | return ERR_VAL; |
||
407 | } |
||
408 | |||
409 | switch(cmd) { |
||
410 | case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ |
||
411 | if (!arg) { |
||
412 | goto fail; |
||
413 | } |
||
414 | *(int *)arg = (int)(0 |
||
415 | #if PPP_IPV4_SUPPORT |
||
416 | || pcb->if4_up |
||
417 | #endif /* PPP_IPV4_SUPPORT */ |
||
418 | #if PPP_IPV6_SUPPORT |
||
419 | || pcb->if6_up |
||
420 | #endif /* PPP_IPV6_SUPPORT */ |
||
421 | ); |
||
422 | return ERR_OK; |
||
423 | |||
424 | case PPPCTLG_ERRCODE: /* Get the PPP error code. */ |
||
425 | if (!arg) { |
||
426 | goto fail; |
||
427 | } |
||
428 | *(int *)arg = (int)(pcb->err_code); |
||
429 | return ERR_OK; |
||
430 | |||
431 | default: |
||
432 | goto fail; |
||
433 | } |
||
434 | |||
435 | fail: |
||
436 | return ERR_VAL; |
||
437 | } |
||
438 | |||
439 | |||
440 | /**********************************/ |
||
441 | /*** LOCAL FUNCTION DEFINITIONS ***/ |
||
442 | /**********************************/ |
||
443 | |||
444 | static void ppp_do_connect(void *arg) { |
||
445 | ppp_pcb *pcb = (ppp_pcb*)arg; |
||
446 | |||
447 | LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF); |
||
448 | |||
449 | new_phase(pcb, PPP_PHASE_INITIALIZE); |
||
450 | pcb->link_cb->connect(pcb, pcb->link_ctx_cb); |
||
451 | } |
||
452 | |||
453 | /* |
||
454 | * ppp_netif_init_cb - netif init callback |
||
455 | */ |
||
456 | static err_t ppp_netif_init_cb(struct netif *netif) { |
||
457 | netif->name[0] = 'p'; |
||
458 | netif->name[1] = 'p'; |
||
459 | #if LWIP_IPV4 |
||
460 | /* FIXME: change that when netif_null_output_ip4() will materialize */ |
||
461 | netif->output = ppp_netif_output_ip4; |
||
462 | #endif /* LWIP_IPV4 */ |
||
463 | #if PPP_IPV6_SUPPORT |
||
464 | netif->output_ip6 = ppp_netif_output_ip6; |
||
465 | #endif /* PPP_IPV6_SUPPORT */ |
||
466 | netif->flags = NETIF_FLAG_UP; |
||
467 | #if LWIP_NETIF_HOSTNAME |
||
468 | /* @todo: Initialize interface hostname */ |
||
469 | /* netif_set_hostname(netif, "lwip"); */ |
||
470 | #endif /* LWIP_NETIF_HOSTNAME */ |
||
471 | return ERR_OK; |
||
472 | } |
||
473 | |||
474 | #if LWIP_IPV4 |
||
475 | /* |
||
476 | * Send an IPv4 packet on the given connection. |
||
477 | */ |
||
478 | static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr) { |
||
479 | LWIP_UNUSED_ARG(ipaddr); |
||
480 | #if PPP_IPV4_SUPPORT |
||
481 | return ppp_netif_output(netif, pb, PPP_IP); |
||
482 | #else /* PPP_IPV4_SUPPORT */ |
||
483 | LWIP_UNUSED_ARG(netif); |
||
484 | LWIP_UNUSED_ARG(pb); |
||
485 | return ERR_IF; |
||
486 | #endif /* PPP_IPV4_SUPPORT */ |
||
487 | } |
||
488 | #endif /* LWIP_IPV4 */ |
||
489 | |||
490 | #if PPP_IPV6_SUPPORT |
||
491 | /* |
||
492 | * Send an IPv6 packet on the given connection. |
||
493 | */ |
||
494 | static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr) { |
||
495 | LWIP_UNUSED_ARG(ipaddr); |
||
496 | return ppp_netif_output(netif, pb, PPP_IPV6); |
||
497 | } |
||
498 | #endif /* PPP_IPV6_SUPPORT */ |
||
499 | |||
500 | static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol) { |
||
501 | ppp_pcb *pcb = (ppp_pcb*)netif->state; |
||
502 | err_t err; |
||
503 | struct pbuf *fpb = NULL; |
||
504 | |||
505 | /* Check that the link is up. */ |
||
506 | if (0 |
||
507 | #if PPP_IPV4_SUPPORT |
||
508 | || (protocol == PPP_IP && !pcb->if4_up) |
||
509 | #endif /* PPP_IPV4_SUPPORT */ |
||
510 | #if PPP_IPV6_SUPPORT |
||
511 | || (protocol == PPP_IPV6 && !pcb->if6_up) |
||
512 | #endif /* PPP_IPV6_SUPPORT */ |
||
513 | ) { |
||
514 | PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->netif->num)); |
||
515 | goto err_rte_drop; |
||
516 | } |
||
517 | |||
518 | #if MPPE_SUPPORT |
||
519 | /* If MPPE is required, refuse any IP packet until we are able to crypt them. */ |
||
520 | if (pcb->settings.require_mppe && pcb->ccp_transmit_method != CI_MPPE) { |
||
521 | PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: MPPE required, not up\n", pcb->netif->num)); |
||
522 | goto err_rte_drop; |
||
523 | } |
||
524 | #endif /* MPPE_SUPPORT */ |
||
525 | |||
526 | #if VJ_SUPPORT |
||
527 | /* |
||
528 | * Attempt Van Jacobson header compression if VJ is configured and |
||
529 | * this is an IP packet. |
||
530 | */ |
||
531 | if (protocol == PPP_IP && pcb->vj_enabled) { |
||
532 | switch (vj_compress_tcp(&pcb->vj_comp, &pb)) { |
||
533 | case TYPE_IP: |
||
534 | /* No change... |
||
535 | protocol = PPP_IP; */ |
||
536 | break; |
||
537 | case TYPE_COMPRESSED_TCP: |
||
538 | /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free |
||
539 | * our duplicated pbuf later */ |
||
540 | fpb = pb; |
||
541 | protocol = PPP_VJC_COMP; |
||
542 | break; |
||
543 | case TYPE_UNCOMPRESSED_TCP: |
||
544 | /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free |
||
545 | * our duplicated pbuf later */ |
||
546 | fpb = pb; |
||
547 | protocol = PPP_VJC_UNCOMP; |
||
548 | break; |
||
549 | default: |
||
550 | PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->netif->num)); |
||
551 | LINK_STATS_INC(link.proterr); |
||
552 | LINK_STATS_INC(link.drop); |
||
553 | MIB2_STATS_NETIF_INC(pcb->netif, ifoutdiscards); |
||
554 | return ERR_VAL; |
||
555 | } |
||
556 | } |
||
557 | #endif /* VJ_SUPPORT */ |
||
558 | |||
559 | #if CCP_SUPPORT |
||
560 | switch (pcb->ccp_transmit_method) { |
||
561 | case 0: |
||
562 | break; /* Don't compress */ |
||
563 | #if MPPE_SUPPORT |
||
564 | case CI_MPPE: |
||
565 | if ((err = mppe_compress(pcb, &pcb->mppe_comp, &pb, protocol)) != ERR_OK) { |
||
566 | LINK_STATS_INC(link.memerr); |
||
567 | LINK_STATS_INC(link.drop); |
||
568 | MIB2_STATS_NETIF_INC(netif, ifoutdiscards); |
||
569 | goto err; |
||
570 | } |
||
571 | /* if VJ compressor returned a new allocated pbuf, free it */ |
||
572 | if (fpb) { |
||
573 | pbuf_free(fpb); |
||
574 | } |
||
575 | /* mppe_compress() returns a new allocated pbuf, indicate we should free |
||
576 | * our duplicated pbuf later */ |
||
577 | fpb = pb; |
||
578 | protocol = PPP_COMP; |
||
579 | break; |
||
580 | #endif /* MPPE_SUPPORT */ |
||
581 | default: |
||
582 | PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: bad CCP transmit method\n", pcb->netif->num)); |
||
583 | goto err_rte_drop; /* Cannot really happen, we only negotiate what we are able to do */ |
||
584 | } |
||
585 | #endif /* CCP_SUPPORT */ |
||
586 | |||
587 | err = pcb->link_cb->netif_output(pcb, pcb->link_ctx_cb, pb, protocol); |
||
588 | goto err; |
||
589 | |||
590 | err_rte_drop: |
||
591 | err = ERR_RTE; |
||
592 | LINK_STATS_INC(link.rterr); |
||
593 | LINK_STATS_INC(link.drop); |
||
594 | MIB2_STATS_NETIF_INC(netif, ifoutdiscards); |
||
595 | err: |
||
596 | if (fpb) { |
||
597 | pbuf_free(fpb); |
||
598 | } |
||
599 | return err; |
||
600 | } |
||
601 | |||
602 | /************************************/ |
||
603 | /*** PRIVATE FUNCTION DEFINITIONS ***/ |
||
604 | /************************************/ |
||
605 | |||
606 | /* Initialize the PPP subsystem. */ |
||
607 | int ppp_init(void) |
||
608 | { |
||
609 | #if PPPOS_SUPPORT |
||
610 | LWIP_MEMPOOL_INIT(PPPOS_PCB); |
||
611 | #endif |
||
612 | #if PPPOE_SUPPORT |
||
613 | LWIP_MEMPOOL_INIT(PPPOE_IF); |
||
614 | #endif |
||
615 | #if PPPOL2TP_SUPPORT |
||
616 | LWIP_MEMPOOL_INIT(PPPOL2TP_PCB); |
||
617 | #endif |
||
618 | #if LWIP_PPP_API && LWIP_MPU_COMPATIBLE |
||
619 | LWIP_MEMPOOL_INIT(PPPAPI_MSG); |
||
620 | #endif |
||
621 | |||
622 | LWIP_MEMPOOL_INIT(PPP_PCB); |
||
623 | |||
624 | /* |
||
625 | * Initialize magic number generator now so that protocols may |
||
626 | * use magic numbers in initialization. |
||
627 | */ |
||
628 | magic_init(); |
||
629 | |||
630 | return 0; |
||
631 | } |
||
632 | |||
633 | /* |
||
634 | * Create a new PPP control block. |
||
635 | * |
||
636 | * This initializes the PPP control block but does not |
||
637 | * attempt to negotiate the LCP session. |
||
638 | * |
||
639 | * Return a new PPP connection control block pointer |
||
640 | * on success or a null pointer on failure. |
||
641 | */ |
||
642 | ppp_pcb *ppp_new(struct netif *pppif, const struct link_callbacks *callbacks, void *link_ctx_cb, ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { |
||
643 | ppp_pcb *pcb; |
||
644 | const struct protent *protp; |
||
645 | int i; |
||
646 | |||
647 | /* PPP is single-threaded: without a callback, |
||
648 | * there is no way to know when the link is up. */ |
||
649 | if (link_status_cb == NULL) { |
||
650 | return NULL; |
||
651 | } |
||
652 | |||
653 | pcb = (ppp_pcb*)LWIP_MEMPOOL_ALLOC(PPP_PCB); |
||
654 | if (pcb == NULL) { |
||
655 | return NULL; |
||
656 | } |
||
657 | |||
658 | memset(pcb, 0, sizeof(ppp_pcb)); |
||
659 | |||
660 | /* default configuration */ |
||
661 | #if PAP_SUPPORT |
||
662 | pcb->settings.pap_timeout_time = UPAP_DEFTIMEOUT; |
||
663 | pcb->settings.pap_max_transmits = UPAP_DEFTRANSMITS; |
||
664 | #if PPP_SERVER |
||
665 | pcb->settings.pap_req_timeout = UPAP_DEFREQTIME; |
||
666 | #endif /* PPP_SERVER */ |
||
667 | #endif /* PAP_SUPPORT */ |
||
668 | |||
669 | #if CHAP_SUPPORT |
||
670 | pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; |
||
671 | pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; |
||
672 | #if PPP_SERVER |
||
673 | pcb->settings.chap_rechallenge_time = CHAP_DEFRECHALLENGETIME; |
||
674 | #endif /* PPP_SERVER */ |
||
675 | #endif /* CHAP_SUPPPORT */ |
||
676 | |||
677 | #if EAP_SUPPORT |
||
678 | pcb->settings.eap_req_time = EAP_DEFREQTIME; |
||
679 | pcb->settings.eap_allow_req = EAP_DEFALLOWREQ; |
||
680 | #if PPP_SERVER |
||
681 | pcb->settings.eap_timeout_time = EAP_DEFTIMEOUT; |
||
682 | pcb->settings.eap_max_transmits = EAP_DEFTRANSMITS; |
||
683 | #endif /* PPP_SERVER */ |
||
684 | #endif /* EAP_SUPPORT */ |
||
685 | |||
686 | pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL; |
||
687 | pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; |
||
688 | pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; |
||
689 | |||
690 | pcb->settings.fsm_timeout_time = FSM_DEFTIMEOUT; |
||
691 | pcb->settings.fsm_max_conf_req_transmits = FSM_DEFMAXCONFREQS; |
||
692 | pcb->settings.fsm_max_term_transmits = FSM_DEFMAXTERMREQS; |
||
693 | pcb->settings.fsm_max_nak_loops = FSM_DEFMAXNAKLOOPS; |
||
694 | |||
695 | pcb->netif = pppif; |
||
696 | MIB2_INIT_NETIF(pppif, snmp_ifType_ppp, 0); |
||
697 | if (!netif_add(pcb->netif, |
||
698 | #if LWIP_IPV4 |
||
699 | IP4_ADDR_ANY4, IP4_ADDR_BROADCAST, IP4_ADDR_ANY4, |
||
700 | #endif /* LWIP_IPV4 */ |
||
701 | (void *)pcb, ppp_netif_init_cb, NULL)) { |
||
702 | LWIP_MEMPOOL_FREE(PPP_PCB, pcb); |
||
703 | PPPDEBUG(LOG_ERR, ("ppp_new: netif_add failed\n")); |
||
704 | return NULL; |
||
705 | } |
||
706 | |||
707 | pcb->link_cb = callbacks; |
||
708 | pcb->link_ctx_cb = link_ctx_cb; |
||
709 | pcb->link_status_cb = link_status_cb; |
||
710 | pcb->ctx_cb = ctx_cb; |
||
711 | |||
712 | /* |
||
713 | * Initialize each protocol. |
||
714 | */ |
||
715 | for (i = 0; (protp = protocols[i]) != NULL; ++i) { |
||
716 | (*protp->init)(pcb); |
||
717 | } |
||
718 | |||
719 | new_phase(pcb, PPP_PHASE_DEAD); |
||
720 | return pcb; |
||
721 | } |
||
722 | |||
723 | /** Initiate LCP open request */ |
||
724 | void ppp_start(ppp_pcb *pcb) { |
||
725 | PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]\n", pcb->netif->num)); |
||
726 | |||
727 | /* Clean data not taken care by anything else, mostly shared data. */ |
||
728 | #if PPP_STATS_SUPPORT |
||
729 | link_stats_valid = 0; |
||
730 | #endif /* PPP_STATS_SUPPORT */ |
||
731 | #if MPPE_SUPPORT |
||
732 | pcb->mppe_keys_set = 0; |
||
733 | memset(&pcb->mppe_comp, 0, sizeof(pcb->mppe_comp)); |
||
734 | memset(&pcb->mppe_decomp, 0, sizeof(pcb->mppe_decomp)); |
||
735 | #endif /* MPPE_SUPPORT */ |
||
736 | #if VJ_SUPPORT |
||
737 | vj_compress_init(&pcb->vj_comp); |
||
738 | #endif /* VJ_SUPPORT */ |
||
739 | |||
740 | /* Start protocol */ |
||
741 | new_phase(pcb, PPP_PHASE_ESTABLISH); |
||
742 | lcp_open(pcb); |
||
743 | lcp_lowerup(pcb); |
||
744 | PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]: finished\n", pcb->netif->num)); |
||
745 | } |
||
746 | |||
747 | /** Called when link failed to setup */ |
||
748 | void ppp_link_failed(ppp_pcb *pcb) { |
||
749 | PPPDEBUG(LOG_DEBUG, ("ppp_link_failed[%d]\n", pcb->netif->num)); |
||
750 | new_phase(pcb, PPP_PHASE_DEAD); |
||
751 | pcb->err_code = PPPERR_OPEN; |
||
752 | pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); |
||
753 | } |
||
754 | |||
755 | /** Called when link is normally down (i.e. it was asked to end) */ |
||
756 | void ppp_link_end(ppp_pcb *pcb) { |
||
757 | PPPDEBUG(LOG_DEBUG, ("ppp_link_end[%d]\n", pcb->netif->num)); |
||
758 | new_phase(pcb, PPP_PHASE_DEAD); |
||
759 | if (pcb->err_code == PPPERR_NONE) { |
||
760 | pcb->err_code = PPPERR_CONNECT; |
||
761 | } |
||
762 | pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); |
||
763 | } |
||
764 | |||
765 | /* |
||
766 | * Pass the processed input packet to the appropriate handler. |
||
767 | * This function and all handlers run in the context of the tcpip_thread |
||
768 | */ |
||
769 | void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { |
||
770 | u16_t protocol; |
||
771 | #if PPP_DEBUG && PPP_PROTOCOLNAME |
||
772 | const char *pname; |
||
773 | #endif /* PPP_DEBUG && PPP_PROTOCOLNAME */ |
||
774 | |||
775 | magic_randomize(); |
||
776 | |||
777 | if (pb->len < 2) { |
||
778 | PPPDEBUG(LOG_ERR, ("ppp_input[%d]: packet too short\n", pcb->netif->num)); |
||
779 | goto drop; |
||
780 | } |
||
781 | protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; |
||
782 | |||
783 | #if PRINTPKT_SUPPORT |
||
784 | ppp_dump_packet(pcb, "rcvd", (unsigned char *)pb->payload, pb->len); |
||
785 | #endif /* PRINTPKT_SUPPORT */ |
||
786 | |||
787 | pbuf_remove_header(pb, sizeof(protocol)); |
||
788 | |||
789 | LINK_STATS_INC(link.recv); |
||
790 | MIB2_STATS_NETIF_INC(pcb->netif, ifinucastpkts); |
||
791 | MIB2_STATS_NETIF_ADD(pcb->netif, ifinoctets, pb->tot_len); |
||
792 | |||
793 | /* |
||
794 | * Toss all non-LCP packets unless LCP is OPEN. |
||
795 | */ |
||
796 | if (protocol != PPP_LCP && pcb->lcp_fsm.state != PPP_FSM_OPENED) { |
||
797 | ppp_dbglog("Discarded non-LCP packet when LCP not open"); |
||
798 | goto drop; |
||
799 | } |
||
800 | |||
801 | /* |
||
802 | * Until we get past the authentication phase, toss all packets |
||
803 | * except LCP, LQR and authentication packets. |
||
804 | */ |
||
805 | if (pcb->phase <= PPP_PHASE_AUTHENTICATE |
||
806 | && !(protocol == PPP_LCP |
||
807 | #if LQR_SUPPORT |
||
808 | || protocol == PPP_LQR |
||
809 | #endif /* LQR_SUPPORT */ |
||
810 | #if PAP_SUPPORT |
||
811 | || protocol == PPP_PAP |
||
812 | #endif /* PAP_SUPPORT */ |
||
813 | #if CHAP_SUPPORT |
||
814 | || protocol == PPP_CHAP |
||
815 | #endif /* CHAP_SUPPORT */ |
||
816 | #if EAP_SUPPORT |
||
817 | || protocol == PPP_EAP |
||
818 | #endif /* EAP_SUPPORT */ |
||
819 | )) { |
||
820 | ppp_dbglog("discarding proto 0x%x in phase %d", protocol, pcb->phase); |
||
821 | goto drop; |
||
822 | } |
||
823 | |||
824 | #if CCP_SUPPORT |
||
825 | #if MPPE_SUPPORT |
||
826 | /* |
||
827 | * MPPE is required and unencrypted data has arrived (this |
||
828 | * should never happen!). We should probably drop the link if |
||
829 | * the protocol is in the range of what should be encrypted. |
||
830 | * At the least, we drop this packet. |
||
831 | */ |
||
832 | if (pcb->settings.require_mppe && protocol != PPP_COMP && protocol < 0x8000) { |
||
833 | PPPDEBUG(LOG_ERR, ("ppp_input[%d]: MPPE required, received unencrypted data!\n", pcb->netif->num)); |
||
834 | goto drop; |
||
835 | } |
||
836 | #endif /* MPPE_SUPPORT */ |
||
837 | |||
838 | if (protocol == PPP_COMP) { |
||
839 | u8_t *pl; |
||
840 | |||
841 | switch (pcb->ccp_receive_method) { |
||
842 | #if MPPE_SUPPORT |
||
843 | case CI_MPPE: |
||
844 | if (mppe_decompress(pcb, &pcb->mppe_decomp, &pb) != ERR_OK) { |
||
845 | goto drop; |
||
846 | } |
||
847 | break; |
||
848 | #endif /* MPPE_SUPPORT */ |
||
849 | default: |
||
850 | PPPDEBUG(LOG_ERR, ("ppp_input[%d]: bad CCP receive method\n", pcb->netif->num)); |
||
851 | goto drop; /* Cannot really happen, we only negotiate what we are able to do */ |
||
852 | } |
||
853 | |||
854 | /* Assume no PFC */ |
||
855 | if (pb->len < 2) { |
||
856 | goto drop; |
||
857 | } |
||
858 | |||
859 | /* Extract and hide protocol (do PFC decompression if necessary) */ |
||
860 | pl = (u8_t*)pb->payload; |
||
861 | if (pl[0] & 0x01) { |
||
862 | protocol = pl[0]; |
||
863 | pbuf_remove_header(pb, 1); |
||
864 | } else { |
||
865 | protocol = (pl[0] << 8) | pl[1]; |
||
866 | pbuf_remove_header(pb, 2); |
||
867 | } |
||
868 | } |
||
869 | #endif /* CCP_SUPPORT */ |
||
870 | |||
871 | switch(protocol) { |
||
872 | |||
873 | #if PPP_IPV4_SUPPORT |
||
874 | case PPP_IP: /* Internet Protocol */ |
||
875 | PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); |
||
876 | ip4_input(pb, pcb->netif); |
||
877 | return; |
||
878 | #endif /* PPP_IPV4_SUPPORT */ |
||
879 | |||
880 | #if PPP_IPV6_SUPPORT |
||
881 | case PPP_IPV6: /* Internet Protocol Version 6 */ |
||
882 | PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip6 in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); |
||
883 | ip6_input(pb, pcb->netif); |
||
884 | return; |
||
885 | #endif /* PPP_IPV6_SUPPORT */ |
||
886 | |||
887 | #if VJ_SUPPORT |
||
888 | case PPP_VJC_COMP: /* VJ compressed TCP */ |
||
889 | /* |
||
890 | * Clip off the VJ header and prepend the rebuilt TCP/IP header and |
||
891 | * pass the result to IP. |
||
892 | */ |
||
893 | PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); |
||
894 | if (pcb->vj_enabled && vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) { |
||
895 | ip4_input(pb, pcb->netif); |
||
896 | return; |
||
897 | } |
||
898 | /* Something's wrong so drop it. */ |
||
899 | PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->netif->num)); |
||
900 | break; |
||
901 | |||
902 | case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ |
||
903 | /* |
||
904 | * Process the TCP/IP header for VJ header compression and then pass |
||
905 | * the packet to IP. |
||
906 | */ |
||
907 | PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); |
||
908 | if (pcb->vj_enabled && vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) { |
||
909 | ip4_input(pb, pcb->netif); |
||
910 | return; |
||
911 | } |
||
912 | /* Something's wrong so drop it. */ |
||
913 | PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->netif->num)); |
||
914 | break; |
||
915 | #endif /* VJ_SUPPORT */ |
||
916 | |||
917 | default: { |
||
918 | int i; |
||
919 | const struct protent *protp; |
||
920 | |||
921 | /* |
||
922 | * Upcall the proper protocol input routine. |
||
923 | */ |
||
924 | for (i = 0; (protp = protocols[i]) != NULL; ++i) { |
||
925 | if (protp->protocol == protocol) { |
||
926 | pb = pbuf_coalesce(pb, PBUF_RAW); |
||
927 | (*protp->input)(pcb, (u8_t*)pb->payload, pb->len); |
||
928 | goto out; |
||
929 | } |
||
930 | #if 0 /* UNUSED |
||
931 | * |
||
932 | * This is actually a (hacked?) way for the Linux kernel to pass a data |
||
933 | * packet to pppd. pppd in normal condition only do signaling |
||
934 | * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. |
||
935 | * |
||
936 | * We don't even need this interface, which is only there because of PPP |
||
937 | * interface limitation between Linux kernel and pppd. For MPPE, which uses |
||
938 | * CCP to negotiate although it is not really a (de)compressor, we added |
||
939 | * ccp_resetrequest() in CCP and MPPE input data flow is calling either |
||
940 | * ccp_resetrequest() or lcp_close() if the issue is, respectively, non-fatal |
||
941 | * or fatal, this is what ccp_datainput() really do. |
||
942 | */ |
||
943 | if (protocol == (protp->protocol & ~0x8000) |
||
944 | && protp->datainput != NULL) { |
||
945 | (*protp->datainput)(pcb, pb->payload, pb->len); |
||
946 | goto out; |
||
947 | } |
||
948 | #endif /* UNUSED */ |
||
949 | } |
||
950 | |||
951 | #if PPP_DEBUG |
||
952 | #if PPP_PROTOCOLNAME |
||
953 | pname = protocol_name(protocol); |
||
954 | if (pname != NULL) { |
||
955 | ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); |
||
956 | } else |
||
957 | #endif /* PPP_PROTOCOLNAME */ |
||
958 | ppp_warn("Unsupported protocol 0x%x received", protocol); |
||
959 | #endif /* PPP_DEBUG */ |
||
960 | pbuf_add_header(pb, sizeof(protocol)); |
||
961 | lcp_sprotrej(pcb, (u8_t*)pb->payload, pb->len); |
||
962 | } |
||
963 | break; |
||
964 | } |
||
965 | |||
966 | drop: |
||
967 | LINK_STATS_INC(link.drop); |
||
968 | MIB2_STATS_NETIF_INC(pcb->netif, ifindiscards); |
||
969 | |||
970 | out: |
||
971 | pbuf_free(pb); |
||
972 | } |
||
973 | |||
974 | /* |
||
975 | * Write a pbuf to a ppp link, only used from PPP functions |
||
976 | * to send PPP packets. |
||
977 | * |
||
978 | * IPv4 and IPv6 packets from lwIP are sent, respectively, |
||
979 | * with ppp_netif_output_ip4() and ppp_netif_output_ip6() |
||
980 | * functions (which are callbacks of the netif PPP interface). |
||
981 | */ |
||
982 | err_t ppp_write(ppp_pcb *pcb, struct pbuf *p) { |
||
983 | #if PRINTPKT_SUPPORT |
||
984 | ppp_dump_packet(pcb, "sent", (unsigned char *)p->payload+2, p->len-2); |
||
985 | #endif /* PRINTPKT_SUPPORT */ |
||
986 | return pcb->link_cb->write(pcb, pcb->link_ctx_cb, p); |
||
987 | } |
||
988 | |||
989 | void ppp_link_terminated(ppp_pcb *pcb) { |
||
990 | PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]\n", pcb->netif->num)); |
||
991 | pcb->link_cb->disconnect(pcb, pcb->link_ctx_cb); |
||
992 | PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]: finished.\n", pcb->netif->num)); |
||
993 | } |
||
994 | |||
995 | |||
996 | /************************************************************************ |
||
997 | * Functions called by various PPP subsystems to configure |
||
998 | * the PPP interface or change the PPP phase. |
||
999 | */ |
||
1000 | |||
1001 | /* |
||
1002 | * new_phase - signal the start of a new phase of pppd's operation. |
||
1003 | */ |
||
1004 | void new_phase(ppp_pcb *pcb, int p) { |
||
1005 | pcb->phase = p; |
||
1006 | PPPDEBUG(LOG_DEBUG, ("ppp phase changed[%d]: phase=%d\n", pcb->netif->num, pcb->phase)); |
||
1007 | #if PPP_NOTIFY_PHASE |
||
1008 | if (pcb->notify_phase_cb != NULL) { |
||
1009 | pcb->notify_phase_cb(pcb, p, pcb->ctx_cb); |
||
1010 | } |
||
1011 | #endif /* PPP_NOTIFY_PHASE */ |
||
1012 | } |
||
1013 | |||
1014 | /* |
||
1015 | * ppp_send_config - configure the transmit-side characteristics of |
||
1016 | * the ppp interface. |
||
1017 | */ |
||
1018 | int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp) { |
||
1019 | LWIP_UNUSED_ARG(mtu); |
||
1020 | /* pcb->mtu = mtu; -- set correctly with netif_set_mtu */ |
||
1021 | |||
1022 | if (pcb->link_cb->send_config) { |
||
1023 | pcb->link_cb->send_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp); |
||
1024 | } |
||
1025 | |||
1026 | PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->netif->num) ); |
||
1027 | return 0; |
||
1028 | } |
||
1029 | |||
1030 | /* |
||
1031 | * ppp_recv_config - configure the receive-side characteristics of |
||
1032 | * the ppp interface. |
||
1033 | */ |
||
1034 | int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp) { |
||
1035 | LWIP_UNUSED_ARG(mru); |
||
1036 | |||
1037 | if (pcb->link_cb->recv_config) { |
||
1038 | pcb->link_cb->recv_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp); |
||
1039 | } |
||
1040 | |||
1041 | PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->netif->num)); |
||
1042 | return 0; |
||
1043 | } |
||
1044 | |||
1045 | #if PPP_IPV4_SUPPORT |
||
1046 | /* |
||
1047 | * sifaddr - Config the interface IP addresses and netmask. |
||
1048 | */ |
||
1049 | int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask) { |
||
1050 | ip4_addr_t ip, nm, gw; |
||
1051 | |||
1052 | ip4_addr_set_u32(&ip, our_adr); |
||
1053 | ip4_addr_set_u32(&nm, netmask); |
||
1054 | ip4_addr_set_u32(&gw, his_adr); |
||
1055 | netif_set_addr(pcb->netif, &ip, &nm, &gw); |
||
1056 | return 1; |
||
1057 | } |
||
1058 | |||
1059 | /******************************************************************** |
||
1060 | * |
||
1061 | * cifaddr - Clear the interface IP addresses, and delete routes |
||
1062 | * through the interface if possible. |
||
1063 | */ |
||
1064 | int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr) { |
||
1065 | LWIP_UNUSED_ARG(our_adr); |
||
1066 | LWIP_UNUSED_ARG(his_adr); |
||
1067 | |||
1068 | netif_set_addr(pcb->netif, IP4_ADDR_ANY4, IP4_ADDR_BROADCAST, IP4_ADDR_ANY4); |
||
1069 | return 1; |
||
1070 | } |
||
1071 | |||
1072 | #if 0 /* UNUSED - PROXY ARP */ |
||
1073 | /******************************************************************** |
||
1074 | * |
||
1075 | * sifproxyarp - Make a proxy ARP entry for the peer. |
||
1076 | */ |
||
1077 | |||
1078 | int sifproxyarp(ppp_pcb *pcb, u32_t his_adr) { |
||
1079 | LWIP_UNUSED_ARG(pcb); |
||
1080 | LWIP_UNUSED_ARG(his_adr); |
||
1081 | return 0; |
||
1082 | } |
||
1083 | |||
1084 | /******************************************************************** |
||
1085 | * |
||
1086 | * cifproxyarp - Delete the proxy ARP entry for the peer. |
||
1087 | */ |
||
1088 | |||
1089 | int cifproxyarp(ppp_pcb *pcb, u32_t his_adr) { |
||
1090 | LWIP_UNUSED_ARG(pcb); |
||
1091 | LWIP_UNUSED_ARG(his_adr); |
||
1092 | return 0; |
||
1093 | } |
||
1094 | #endif /* UNUSED - PROXY ARP */ |
||
1095 | |||
1096 | #if LWIP_DNS |
||
1097 | /* |
||
1098 | * sdns - Config the DNS servers |
||
1099 | */ |
||
1100 | int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { |
||
1101 | ip_addr_t ns; |
||
1102 | LWIP_UNUSED_ARG(pcb); |
||
1103 | |||
1104 | ip_addr_set_ip4_u32_val(ns, ns1); |
||
1105 | dns_setserver(0, &ns); |
||
1106 | ip_addr_set_ip4_u32_val(ns, ns2); |
||
1107 | dns_setserver(1, &ns); |
||
1108 | return 1; |
||
1109 | } |
||
1110 | |||
1111 | /******************************************************************** |
||
1112 | * |
||
1113 | * cdns - Clear the DNS servers |
||
1114 | */ |
||
1115 | int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { |
||
1116 | const ip_addr_t *nsa; |
||
1117 | ip_addr_t nsb; |
||
1118 | LWIP_UNUSED_ARG(pcb); |
||
1119 | |||
1120 | nsa = dns_getserver(0); |
||
1121 | ip_addr_set_ip4_u32_val(nsb, ns1); |
||
1122 | if (ip_addr_cmp(nsa, &nsb)) { |
||
1123 | dns_setserver(0, IP_ADDR_ANY); |
||
1124 | } |
||
1125 | nsa = dns_getserver(1); |
||
1126 | ip_addr_set_ip4_u32_val(nsb, ns2); |
||
1127 | if (ip_addr_cmp(nsa, &nsb)) { |
||
1128 | dns_setserver(1, IP_ADDR_ANY); |
||
1129 | } |
||
1130 | return 1; |
||
1131 | } |
||
1132 | #endif /* LWIP_DNS */ |
||
1133 | |||
1134 | #if VJ_SUPPORT |
||
1135 | /******************************************************************** |
||
1136 | * |
||
1137 | * sifvjcomp - config tcp header compression |
||
1138 | */ |
||
1139 | int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) { |
||
1140 | pcb->vj_enabled = vjcomp; |
||
1141 | pcb->vj_comp.compressSlot = cidcomp; |
||
1142 | pcb->vj_comp.maxSlotIndex = maxcid; |
||
1143 | PPPDEBUG(LOG_INFO, ("sifvjcomp[%d]: VJ compress enable=%d slot=%d max slot=%d\n", |
||
1144 | pcb->netif->num, vjcomp, cidcomp, maxcid)); |
||
1145 | return 0; |
||
1146 | } |
||
1147 | #endif /* VJ_SUPPORT */ |
||
1148 | |||
1149 | /* |
||
1150 | * sifup - Config the interface up and enable IP packets to pass. |
||
1151 | */ |
||
1152 | int sifup(ppp_pcb *pcb) { |
||
1153 | pcb->if4_up = 1; |
||
1154 | pcb->err_code = PPPERR_NONE; |
||
1155 | netif_set_link_up(pcb->netif); |
||
1156 | |||
1157 | PPPDEBUG(LOG_DEBUG, ("sifup[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); |
||
1158 | pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); |
||
1159 | return 1; |
||
1160 | } |
||
1161 | |||
1162 | /******************************************************************** |
||
1163 | * |
||
1164 | * sifdown - Disable the indicated protocol and config the interface |
||
1165 | * down if there are no remaining protocols. |
||
1166 | */ |
||
1167 | int sifdown(ppp_pcb *pcb) { |
||
1168 | |||
1169 | pcb->if4_up = 0; |
||
1170 | |||
1171 | if (1 |
||
1172 | #if PPP_IPV6_SUPPORT |
||
1173 | /* set the interface down if IPv6 is down as well */ |
||
1174 | && !pcb->if6_up |
||
1175 | #endif /* PPP_IPV6_SUPPORT */ |
||
1176 | ) { |
||
1177 | /* make sure the netif link callback is called */ |
||
1178 | netif_set_link_down(pcb->netif); |
||
1179 | } |
||
1180 | PPPDEBUG(LOG_DEBUG, ("sifdown[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); |
||
1181 | return 1; |
||
1182 | } |
||
1183 | |||
1184 | /******************************************************************** |
||
1185 | * |
||
1186 | * Return user specified netmask, modified by any mask we might determine |
||
1187 | * for address `addr' (in network byte order). |
||
1188 | * Here we scan through the system's list of interfaces, looking for |
||
1189 | * any non-point-to-point interfaces which might appear to be on the same |
||
1190 | * network as `addr'. If we find any, we OR in their netmask to the |
||
1191 | * user-specified netmask. |
||
1192 | */ |
||
1193 | u32_t get_mask(u32_t addr) { |
||
1194 | #if 0 |
||
1195 | u32_t mask, nmask; |
||
1196 | |||
1197 | addr = lwip_htonl(addr); |
||
1198 | if (IP_CLASSA(addr)) { /* determine network mask for address class */ |
||
1199 | nmask = IP_CLASSA_NET; |
||
1200 | } else if (IP_CLASSB(addr)) { |
||
1201 | nmask = IP_CLASSB_NET; |
||
1202 | } else { |
||
1203 | nmask = IP_CLASSC_NET; |
||
1204 | } |
||
1205 | |||
1206 | /* class D nets are disallowed by bad_ip_adrs */ |
||
1207 | mask = PP_HTONL(0xffffff00UL) | lwip_htonl(nmask); |
||
1208 | |||
1209 | /* XXX |
||
1210 | * Scan through the system's network interfaces. |
||
1211 | * Get each netmask and OR them into our mask. |
||
1212 | */ |
||
1213 | /* return mask; */ |
||
1214 | return mask; |
||
1215 | #endif /* 0 */ |
||
1216 | LWIP_UNUSED_ARG(addr); |
||
1217 | return IPADDR_BROADCAST; |
||
1218 | } |
||
1219 | #endif /* PPP_IPV4_SUPPORT */ |
||
1220 | |||
1221 | #if PPP_IPV6_SUPPORT |
||
1222 | #define IN6_LLADDR_FROM_EUI64(ip6, eui64) do { \ |
||
1223 | ip6.addr[0] = PP_HTONL(0xfe800000); \ |
||
1224 | ip6.addr[1] = 0; \ |
||
1225 | eui64_copy(eui64, ip6.addr[2]); \ |
||
1226 | } while (0) |
||
1227 | |||
1228 | /******************************************************************** |
||
1229 | * |
||
1230 | * sif6addr - Config the interface with an IPv6 link-local address |
||
1231 | */ |
||
1232 | int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { |
||
1233 | ip6_addr_t ip6; |
||
1234 | LWIP_UNUSED_ARG(his_eui64); |
||
1235 | |||
1236 | IN6_LLADDR_FROM_EUI64(ip6, our_eui64); |
||
1237 | netif_ip6_addr_set(pcb->netif, 0, &ip6); |
||
1238 | netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_PREFERRED); |
||
1239 | /* FIXME: should we add an IPv6 static neighbor using his_eui64 ? */ |
||
1240 | return 1; |
||
1241 | } |
||
1242 | |||
1243 | /******************************************************************** |
||
1244 | * |
||
1245 | * cif6addr - Remove IPv6 address from interface |
||
1246 | */ |
||
1247 | int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { |
||
1248 | LWIP_UNUSED_ARG(our_eui64); |
||
1249 | LWIP_UNUSED_ARG(his_eui64); |
||
1250 | |||
1251 | netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_INVALID); |
||
1252 | netif_ip6_addr_set(pcb->netif, 0, IP6_ADDR_ANY6); |
||
1253 | return 1; |
||
1254 | } |
||
1255 | |||
1256 | /* |
||
1257 | * sif6up - Config the interface up and enable IPv6 packets to pass. |
||
1258 | */ |
||
1259 | int sif6up(ppp_pcb *pcb) { |
||
1260 | |||
1261 | pcb->if6_up = 1; |
||
1262 | pcb->err_code = PPPERR_NONE; |
||
1263 | netif_set_link_up(pcb->netif); |
||
1264 | |||
1265 | PPPDEBUG(LOG_DEBUG, ("sif6up[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); |
||
1266 | pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); |
||
1267 | return 1; |
||
1268 | } |
||
1269 | |||
1270 | /******************************************************************** |
||
1271 | * |
||
1272 | * sif6down - Disable the indicated protocol and config the interface |
||
1273 | * down if there are no remaining protocols. |
||
1274 | */ |
||
1275 | int sif6down(ppp_pcb *pcb) { |
||
1276 | |||
1277 | pcb->if6_up = 0; |
||
1278 | |||
1279 | if (1 |
||
1280 | #if PPP_IPV4_SUPPORT |
||
1281 | /* set the interface down if IPv4 is down as well */ |
||
1282 | && !pcb->if4_up |
||
1283 | #endif /* PPP_IPV4_SUPPORT */ |
||
1284 | ) { |
||
1285 | /* make sure the netif link callback is called */ |
||
1286 | netif_set_link_down(pcb->netif); |
||
1287 | } |
||
1288 | PPPDEBUG(LOG_DEBUG, ("sif6down[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); |
||
1289 | return 1; |
||
1290 | } |
||
1291 | #endif /* PPP_IPV6_SUPPORT */ |
||
1292 | |||
1293 | #if DEMAND_SUPPORT |
||
1294 | /* |
||
1295 | * sifnpmode - Set the mode for handling packets for a given NP. |
||
1296 | */ |
||
1297 | int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) { |
||
1298 | LWIP_UNUSED_ARG(pcb); |
||
1299 | LWIP_UNUSED_ARG(proto); |
||
1300 | LWIP_UNUSED_ARG(mode); |
||
1301 | return 0; |
||
1302 | } |
||
1303 | #endif /* DEMAND_SUPPORT */ |
||
1304 | |||
1305 | /* |
||
1306 | * netif_set_mtu - set the MTU on the PPP network interface. |
||
1307 | */ |
||
1308 | void netif_set_mtu(ppp_pcb *pcb, int mtu) { |
||
1309 | |||
1310 | pcb->netif->mtu = mtu; |
||
1311 | PPPDEBUG(LOG_INFO, ("netif_set_mtu[%d]: mtu=%d\n", pcb->netif->num, mtu)); |
||
1312 | } |
||
1313 | |||
1314 | /* |
||
1315 | * netif_get_mtu - get PPP interface MTU |
||
1316 | */ |
||
1317 | int netif_get_mtu(ppp_pcb *pcb) { |
||
1318 | |||
1319 | return pcb->netif->mtu; |
||
1320 | } |
||
1321 | |||
1322 | #if CCP_SUPPORT |
||
1323 | #if 0 /* unused */ |
||
1324 | /* |
||
1325 | * ccp_test - whether a given compression method is acceptable for use. |
||
1326 | */ |
||
1327 | int |
||
1328 | ccp_test(ppp_pcb *pcb, u_char *opt_ptr, int opt_len, int for_transmit) |
||
1329 | { |
||
1330 | LWIP_UNUSED_ARG(pcb); |
||
1331 | LWIP_UNUSED_ARG(opt_ptr); |
||
1332 | LWIP_UNUSED_ARG(opt_len); |
||
1333 | LWIP_UNUSED_ARG(for_transmit); |
||
1334 | return -1; |
||
1335 | } |
||
1336 | #endif /* unused */ |
||
1337 | |||
1338 | /* |
||
1339 | * ccp_set - inform about the current state of CCP. |
||
1340 | */ |
||
1341 | void |
||
1342 | ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method) |
||
1343 | { |
||
1344 | LWIP_UNUSED_ARG(isopen); |
||
1345 | LWIP_UNUSED_ARG(isup); |
||
1346 | pcb->ccp_receive_method = receive_method; |
||
1347 | pcb->ccp_transmit_method = transmit_method; |
||
1348 | PPPDEBUG(LOG_DEBUG, ("ccp_set[%d]: is_open=%d, is_up=%d, receive_method=%u, transmit_method=%u\n", |
||
1349 | pcb->netif->num, isopen, isup, receive_method, transmit_method)); |
||
1350 | } |
||
1351 | |||
1352 | void |
||
1353 | ccp_reset_comp(ppp_pcb *pcb) |
||
1354 | { |
||
1355 | switch (pcb->ccp_transmit_method) { |
||
1356 | #if MPPE_SUPPORT |
||
1357 | case CI_MPPE: |
||
1358 | mppe_comp_reset(pcb, &pcb->mppe_comp); |
||
1359 | break; |
||
1360 | #endif /* MPPE_SUPPORT */ |
||
1361 | default: |
||
1362 | break; |
||
1363 | } |
||
1364 | } |
||
1365 | |||
1366 | void |
||
1367 | ccp_reset_decomp(ppp_pcb *pcb) |
||
1368 | { |
||
1369 | switch (pcb->ccp_receive_method) { |
||
1370 | #if MPPE_SUPPORT |
||
1371 | case CI_MPPE: |
||
1372 | mppe_decomp_reset(pcb, &pcb->mppe_decomp); |
||
1373 | break; |
||
1374 | #endif /* MPPE_SUPPORT */ |
||
1375 | default: |
||
1376 | break; |
||
1377 | } |
||
1378 | } |
||
1379 | |||
1380 | #if 0 /* unused */ |
||
1381 | /* |
||
1382 | * ccp_fatal_error - returns 1 if decompression was disabled as a |
||
1383 | * result of an error detected after decompression of a packet, |
||
1384 | * 0 otherwise. This is necessary because of patent nonsense. |
||
1385 | */ |
||
1386 | int |
||
1387 | ccp_fatal_error(ppp_pcb *pcb) |
||
1388 | { |
||
1389 | LWIP_UNUSED_ARG(pcb); |
||
1390 | return 1; |
||
1391 | } |
||
1392 | #endif /* unused */ |
||
1393 | #endif /* CCP_SUPPORT */ |
||
1394 | |||
1395 | #if PPP_IDLETIMELIMIT |
||
1396 | /******************************************************************** |
||
1397 | * |
||
1398 | * get_idle_time - return how long the link has been idle. |
||
1399 | */ |
||
1400 | int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip) { |
||
1401 | /* FIXME: add idle time support and make it optional */ |
||
1402 | LWIP_UNUSED_ARG(pcb); |
||
1403 | LWIP_UNUSED_ARG(ip); |
||
1404 | return 1; |
||
1405 | } |
||
1406 | #endif /* PPP_IDLETIMELIMIT */ |
||
1407 | |||
1408 | #if DEMAND_SUPPORT |
||
1409 | /******************************************************************** |
||
1410 | * |
||
1411 | * get_loop_output - get outgoing packets from the ppp device, |
||
1412 | * and detect when we want to bring the real link up. |
||
1413 | * Return value is 1 if we need to bring up the link, 0 otherwise. |
||
1414 | */ |
||
1415 | int get_loop_output(void) { |
||
1416 | return 0; |
||
1417 | } |
||
1418 | #endif /* DEMAND_SUPPORT */ |
||
1419 | |||
1420 | #if PPP_PROTOCOLNAME |
||
1421 | /* List of protocol names, to make our messages a little more informative. */ |
||
1422 | struct protocol_list { |
||
1423 | u_short proto; |
||
1424 | const char *name; |
||
1425 | } const protocol_list[] = { |
||
1426 | { 0x21, "IP" }, |
||
1427 | { 0x23, "OSI Network Layer" }, |
||
1428 | { 0x25, "Xerox NS IDP" }, |
||
1429 | { 0x27, "DECnet Phase IV" }, |
||
1430 | { 0x29, "Appletalk" }, |
||
1431 | { 0x2b, "Novell IPX" }, |
||
1432 | { 0x2d, "VJ compressed TCP/IP" }, |
||
1433 | { 0x2f, "VJ uncompressed TCP/IP" }, |
||
1434 | { 0x31, "Bridging PDU" }, |
||
1435 | { 0x33, "Stream Protocol ST-II" }, |
||
1436 | { 0x35, "Banyan Vines" }, |
||
1437 | { 0x39, "AppleTalk EDDP" }, |
||
1438 | { 0x3b, "AppleTalk SmartBuffered" }, |
||
1439 | { 0x3d, "Multi-Link" }, |
||
1440 | { 0x3f, "NETBIOS Framing" }, |
||
1441 | { 0x41, "Cisco Systems" }, |
||
1442 | { 0x43, "Ascom Timeplex" }, |
||
1443 | { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, |
||
1444 | { 0x47, "DCA Remote Lan" }, |
||
1445 | { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, |
||
1446 | { 0x4b, "SNA over 802.2" }, |
||
1447 | { 0x4d, "SNA" }, |
||
1448 | { 0x4f, "IP6 Header Compression" }, |
||
1449 | { 0x51, "KNX Bridging Data" }, |
||
1450 | { 0x53, "Encryption" }, |
||
1451 | { 0x55, "Individual Link Encryption" }, |
||
1452 | { 0x57, "IPv6" }, |
||
1453 | { 0x59, "PPP Muxing" }, |
||
1454 | { 0x5b, "Vendor-Specific Network Protocol" }, |
||
1455 | { 0x61, "RTP IPHC Full Header" }, |
||
1456 | { 0x63, "RTP IPHC Compressed TCP" }, |
||
1457 | { 0x65, "RTP IPHC Compressed non-TCP" }, |
||
1458 | { 0x67, "RTP IPHC Compressed UDP 8" }, |
||
1459 | { 0x69, "RTP IPHC Compressed RTP 8" }, |
||
1460 | { 0x6f, "Stampede Bridging" }, |
||
1461 | { 0x73, "MP+" }, |
||
1462 | { 0xc1, "NTCITS IPI" }, |
||
1463 | { 0xfb, "single-link compression" }, |
||
1464 | { 0xfd, "Compressed Datagram" }, |
||
1465 | { 0x0201, "802.1d Hello Packets" }, |
||
1466 | { 0x0203, "IBM Source Routing BPDU" }, |
||
1467 | { 0x0205, "DEC LANBridge100 Spanning Tree" }, |
||
1468 | { 0x0207, "Cisco Discovery Protocol" }, |
||
1469 | { 0x0209, "Netcs Twin Routing" }, |
||
1470 | { 0x020b, "STP - Scheduled Transfer Protocol" }, |
||
1471 | { 0x020d, "EDP - Extreme Discovery Protocol" }, |
||
1472 | { 0x0211, "Optical Supervisory Channel Protocol" }, |
||
1473 | { 0x0213, "Optical Supervisory Channel Protocol" }, |
||
1474 | { 0x0231, "Luxcom" }, |
||
1475 | { 0x0233, "Sigma Network Systems" }, |
||
1476 | { 0x0235, "Apple Client Server Protocol" }, |
||
1477 | { 0x0281, "MPLS Unicast" }, |
||
1478 | { 0x0283, "MPLS Multicast" }, |
||
1479 | { 0x0285, "IEEE p1284.4 standard - data packets" }, |
||
1480 | { 0x0287, "ETSI TETRA Network Protocol Type 1" }, |
||
1481 | { 0x0289, "Multichannel Flow Treatment Protocol" }, |
||
1482 | { 0x2063, "RTP IPHC Compressed TCP No Delta" }, |
||
1483 | { 0x2065, "RTP IPHC Context State" }, |
||
1484 | { 0x2067, "RTP IPHC Compressed UDP 16" }, |
||
1485 | { 0x2069, "RTP IPHC Compressed RTP 16" }, |
||
1486 | { 0x4001, "Cray Communications Control Protocol" }, |
||
1487 | { 0x4003, "CDPD Mobile Network Registration Protocol" }, |
||
1488 | { 0x4005, "Expand accelerator protocol" }, |
||
1489 | { 0x4007, "ODSICP NCP" }, |
||
1490 | { 0x4009, "DOCSIS DLL" }, |
||
1491 | { 0x400B, "Cetacean Network Detection Protocol" }, |
||
1492 | { 0x4021, "Stacker LZS" }, |
||
1493 | { 0x4023, "RefTek Protocol" }, |
||
1494 | { 0x4025, "Fibre Channel" }, |
||
1495 | { 0x4027, "EMIT Protocols" }, |
||
1496 | { 0x405b, "Vendor-Specific Protocol (VSP)" }, |
||
1497 | { 0x8021, "Internet Protocol Control Protocol" }, |
||
1498 | { 0x8023, "OSI Network Layer Control Protocol" }, |
||
1499 | { 0x8025, "Xerox NS IDP Control Protocol" }, |
||
1500 | { 0x8027, "DECnet Phase IV Control Protocol" }, |
||
1501 | { 0x8029, "Appletalk Control Protocol" }, |
||
1502 | { 0x802b, "Novell IPX Control Protocol" }, |
||
1503 | { 0x8031, "Bridging NCP" }, |
||
1504 | { 0x8033, "Stream Protocol Control Protocol" }, |
||
1505 | { 0x8035, "Banyan Vines Control Protocol" }, |
||
1506 | { 0x803d, "Multi-Link Control Protocol" }, |
||
1507 | { 0x803f, "NETBIOS Framing Control Protocol" }, |
||
1508 | { 0x8041, "Cisco Systems Control Protocol" }, |
||
1509 | { 0x8043, "Ascom Timeplex" }, |
||
1510 | { 0x8045, "Fujitsu LBLB Control Protocol" }, |
||
1511 | { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, |
||
1512 | { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, |
||
1513 | { 0x804b, "SNA over 802.2 Control Protocol" }, |
||
1514 | { 0x804d, "SNA Control Protocol" }, |
||
1515 | { 0x804f, "IP6 Header Compression Control Protocol" }, |
||
1516 | { 0x8051, "KNX Bridging Control Protocol" }, |
||
1517 | { 0x8053, "Encryption Control Protocol" }, |
||
1518 | { 0x8055, "Individual Link Encryption Control Protocol" }, |
||
1519 | { 0x8057, "IPv6 Control Protocol" }, |
||
1520 | { 0x8059, "PPP Muxing Control Protocol" }, |
||
1521 | { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, |
||
1522 | { 0x806f, "Stampede Bridging Control Protocol" }, |
||
1523 | { 0x8073, "MP+ Control Protocol" }, |
||
1524 | { 0x80c1, "NTCITS IPI Control Protocol" }, |
||
1525 | { 0x80fb, "Single Link Compression Control Protocol" }, |
||
1526 | { 0x80fd, "Compression Control Protocol" }, |
||
1527 | { 0x8207, "Cisco Discovery Protocol Control" }, |
||
1528 | { 0x8209, "Netcs Twin Routing" }, |
||
1529 | { 0x820b, "STP - Control Protocol" }, |
||
1530 | { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, |
||
1531 | { 0x8235, "Apple Client Server Protocol Control" }, |
||
1532 | { 0x8281, "MPLSCP" }, |
||
1533 | { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, |
||
1534 | { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, |
||
1535 | { 0x8289, "Multichannel Flow Treatment Protocol" }, |
||
1536 | { 0xc021, "Link Control Protocol" }, |
||
1537 | { 0xc023, "Password Authentication Protocol" }, |
||
1538 | { 0xc025, "Link Quality Report" }, |
||
1539 | { 0xc027, "Shiva Password Authentication Protocol" }, |
||
1540 | { 0xc029, "CallBack Control Protocol (CBCP)" }, |
||
1541 | { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, |
||
1542 | { 0xc02d, "BAP" }, |
||
1543 | { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, |
||
1544 | { 0xc081, "Container Control Protocol" }, |
||
1545 | { 0xc223, "Challenge Handshake Authentication Protocol" }, |
||
1546 | { 0xc225, "RSA Authentication Protocol" }, |
||
1547 | { 0xc227, "Extensible Authentication Protocol" }, |
||
1548 | { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, |
||
1549 | { 0xc26f, "Stampede Bridging Authorization Protocol" }, |
||
1550 | { 0xc281, "Proprietary Authentication Protocol" }, |
||
1551 | { 0xc283, "Proprietary Authentication Protocol" }, |
||
1552 | { 0xc481, "Proprietary Node ID Authentication Protocol" }, |
||
1553 | { 0, NULL }, |
||
1554 | }; |
||
1555 | |||
1556 | /* |
||
1557 | * protocol_name - find a name for a PPP protocol. |
||
1558 | */ |
||
1559 | const char * protocol_name(int proto) { |
||
1560 | const struct protocol_list *lp; |
||
1561 | |||
1562 | for (lp = protocol_list; lp->proto != 0; ++lp) { |
||
1563 | if (proto == lp->proto) { |
||
1564 | return lp->name; |
||
1565 | } |
||
1566 | } |
||
1567 | return NULL; |
||
1568 | } |
||
1569 | #endif /* PPP_PROTOCOLNAME */ |
||
1570 | |||
1571 | #if PPP_STATS_SUPPORT |
||
1572 | |||
1573 | /* ---- Note on PPP Stats support ---- |
||
1574 | * |
||
1575 | * The one willing link stats support should add the get_ppp_stats() |
||
1576 | * to fetch statistics from lwIP. |
||
1577 | */ |
||
1578 | |||
1579 | /* |
||
1580 | * reset_link_stats - "reset" stats when link goes up. |
||
1581 | */ |
||
1582 | void reset_link_stats(int u) { |
||
1583 | if (!get_ppp_stats(u, &old_link_stats)) { |
||
1584 | return; |
||
1585 | } |
||
1586 | gettimeofday(&start_time, NULL); |
||
1587 | } |
||
1588 | |||
1589 | /* |
||
1590 | * update_link_stats - get stats at link termination. |
||
1591 | */ |
||
1592 | void update_link_stats(int u) { |
||
1593 | struct timeval now; |
||
1594 | char numbuf[32]; |
||
1595 | |||
1596 | if (!get_ppp_stats(u, &link_stats) || gettimeofday(&now, NULL) < 0) { |
||
1597 | return; |
||
1598 | } |
||
1599 | link_connect_time = now.tv_sec - start_time.tv_sec; |
||
1600 | link_stats_valid = 1; |
||
1601 | |||
1602 | link_stats.bytes_in -= old_link_stats.bytes_in; |
||
1603 | link_stats.bytes_out -= old_link_stats.bytes_out; |
||
1604 | link_stats.pkts_in -= old_link_stats.pkts_in; |
||
1605 | link_stats.pkts_out -= old_link_stats.pkts_out; |
||
1606 | } |
||
1607 | |||
1608 | void print_link_stats() { |
||
1609 | /* |
||
1610 | * Print connect time and statistics. |
||
1611 | */ |
||
1612 | if (link_stats_valid) { |
||
1613 | int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ |
||
1614 | info("Connect time %d.%d minutes.", t/10, t%10); |
||
1615 | info("Sent %u bytes, received %u bytes.", link_stats.bytes_out, link_stats.bytes_in); |
||
1616 | link_stats_valid = 0; |
||
1617 | } |
||
1618 | } |
||
1619 | #endif /* PPP_STATS_SUPPORT */ |
||
1620 | |||
1621 | #endif /* PPP_SUPPORT */ |