1 | /**
|
---|
2 | * @file
|
---|
3 | * Network Point to Point Protocol over Layer 2 Tunneling Protocol program file.
|
---|
4 | *
|
---|
5 | */
|
---|
6 |
|
---|
7 | /*
|
---|
8 | * Redistribution and use in source and binary forms, with or without modification,
|
---|
9 | * are permitted provided that the following conditions are met:
|
---|
10 | *
|
---|
11 | * 1. Redistributions of source code must retain the above copyright notice,
|
---|
12 | * this list of conditions and the following disclaimer.
|
---|
13 | * 2. Redistributions in binary form must reproduce the above copyright notice,
|
---|
14 | * this list of conditions and the following disclaimer in the documentation
|
---|
15 | * and/or other materials provided with the distribution.
|
---|
16 | * 3. The name of the author may not be used to endorse or promote products
|
---|
17 | * derived from this software without specific prior written permission.
|
---|
18 | *
|
---|
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
---|
20 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
---|
21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
---|
22 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
---|
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
---|
24 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
---|
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
---|
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
---|
27 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
---|
28 | * OF SUCH DAMAGE.
|
---|
29 | *
|
---|
30 | * This file is part of the lwIP TCP/IP stack.
|
---|
31 | *
|
---|
32 | */
|
---|
33 |
|
---|
34 | /*
|
---|
35 | * L2TP Support status:
|
---|
36 | *
|
---|
37 | * Supported:
|
---|
38 | * - L2TPv2 (PPP over L2TP, a.k.a. UDP tunnels)
|
---|
39 | * - LAC
|
---|
40 | *
|
---|
41 | * Not supported:
|
---|
42 | * - LNS (require PPP server support)
|
---|
43 | * - L2TPv3 ethernet pseudowires
|
---|
44 | * - L2TPv3 VLAN pseudowire
|
---|
45 | * - L2TPv3 PPP pseudowires
|
---|
46 | * - L2TPv3 IP encapsulation
|
---|
47 | * - L2TPv3 IP pseudowire
|
---|
48 | * - L2TP tunnel switching - http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08
|
---|
49 | * - Multiple tunnels per UDP socket, as well as multiple sessions per tunnel
|
---|
50 | * - Hidden AVPs
|
---|
51 | */
|
---|
52 |
|
---|
53 | #include "netif/ppp/ppp_opts.h"
|
---|
54 | #if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */
|
---|
55 |
|
---|
56 | #include "lwip/err.h"
|
---|
57 | #include "lwip/memp.h"
|
---|
58 | #include "lwip/netif.h"
|
---|
59 | #include "lwip/udp.h"
|
---|
60 | #include "lwip/snmp.h"
|
---|
61 |
|
---|
62 | #include "netif/ppp/ppp_impl.h"
|
---|
63 | #include "netif/ppp/lcp.h"
|
---|
64 | #include "netif/ppp/ipcp.h"
|
---|
65 | #include "netif/ppp/pppol2tp.h"
|
---|
66 | #include "netif/ppp/pppcrypt.h"
|
---|
67 | #include "netif/ppp/magic.h"
|
---|
68 |
|
---|
69 | /* Memory pool */
|
---|
70 | LWIP_MEMPOOL_DECLARE(PPPOL2TP_PCB, MEMP_NUM_PPPOL2TP_INTERFACES, sizeof(pppol2tp_pcb), "PPPOL2TP_PCB")
|
---|
71 |
|
---|
72 | /* callbacks called from PPP core */
|
---|
73 | static err_t pppol2tp_write(ppp_pcb *ppp, void *ctx, struct pbuf *p);
|
---|
74 | static err_t pppol2tp_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol);
|
---|
75 | static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx); /* Destroy a L2TP control block */
|
---|
76 | static void pppol2tp_connect(ppp_pcb *ppp, void *ctx); /* Be a LAC, connect to a LNS. */
|
---|
77 | static void pppol2tp_disconnect(ppp_pcb *ppp, void *ctx); /* Disconnect */
|
---|
78 |
|
---|
79 | /* Prototypes for procedures local to this file. */
|
---|
80 | static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
|
---|
81 | static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, struct pbuf *p, u16_t ns, u16_t nr);
|
---|
82 | static void pppol2tp_timeout(void *arg);
|
---|
83 | static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp);
|
---|
84 | static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp);
|
---|
85 | static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns);
|
---|
86 | static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns);
|
---|
87 | static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns);
|
---|
88 | static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns, u16_t nr);
|
---|
89 | static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns);
|
---|
90 | static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb);
|
---|
91 | static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb);
|
---|
92 |
|
---|
93 | /* Callbacks structure for PPP core */
|
---|
94 | static const struct link_callbacks pppol2tp_callbacks = {
|
---|
95 | pppol2tp_connect,
|
---|
96 | #if PPP_SERVER
|
---|
97 | NULL,
|
---|
98 | #endif /* PPP_SERVER */
|
---|
99 | pppol2tp_disconnect,
|
---|
100 | pppol2tp_destroy,
|
---|
101 | pppol2tp_write,
|
---|
102 | pppol2tp_netif_output,
|
---|
103 | NULL,
|
---|
104 | NULL
|
---|
105 | };
|
---|
106 |
|
---|
107 |
|
---|
108 | /* Create a new L2TP session. */
|
---|
109 | ppp_pcb *pppol2tp_create(struct netif *pppif,
|
---|
110 | struct netif *netif, const ip_addr_t *ipaddr, u16_t port,
|
---|
111 | const u8_t *secret, u8_t secret_len,
|
---|
112 | ppp_link_status_cb_fn link_status_cb, void *ctx_cb) {
|
---|
113 | ppp_pcb *ppp;
|
---|
114 | pppol2tp_pcb *l2tp;
|
---|
115 | struct udp_pcb *udp;
|
---|
116 | #if !PPPOL2TP_AUTH_SUPPORT
|
---|
117 | LWIP_UNUSED_ARG(secret);
|
---|
118 | LWIP_UNUSED_ARG(secret_len);
|
---|
119 | #endif /* !PPPOL2TP_AUTH_SUPPORT */
|
---|
120 |
|
---|
121 | if (ipaddr == NULL) {
|
---|
122 | goto ipaddr_check_failed;
|
---|
123 | }
|
---|
124 |
|
---|
125 | l2tp = (pppol2tp_pcb *)LWIP_MEMPOOL_ALLOC(PPPOL2TP_PCB);
|
---|
126 | if (l2tp == NULL) {
|
---|
127 | goto memp_malloc_l2tp_failed;
|
---|
128 | }
|
---|
129 |
|
---|
130 | udp = udp_new_ip_type(IP_GET_TYPE(ipaddr));
|
---|
131 | if (udp == NULL) {
|
---|
132 | goto udp_new_failed;
|
---|
133 | }
|
---|
134 | udp_recv(udp, pppol2tp_input, l2tp);
|
---|
135 |
|
---|
136 | ppp = ppp_new(pppif, &pppol2tp_callbacks, l2tp, link_status_cb, ctx_cb);
|
---|
137 | if (ppp == NULL) {
|
---|
138 | goto ppp_new_failed;
|
---|
139 | }
|
---|
140 |
|
---|
141 | memset(l2tp, 0, sizeof(pppol2tp_pcb));
|
---|
142 | l2tp->phase = PPPOL2TP_STATE_INITIAL;
|
---|
143 | l2tp->ppp = ppp;
|
---|
144 | l2tp->udp = udp;
|
---|
145 | l2tp->netif = netif;
|
---|
146 | ip_addr_copy(l2tp->remote_ip, *ipaddr);
|
---|
147 | l2tp->remote_port = port;
|
---|
148 | #if PPPOL2TP_AUTH_SUPPORT
|
---|
149 | l2tp->secret = secret;
|
---|
150 | l2tp->secret_len = secret_len;
|
---|
151 | #endif /* PPPOL2TP_AUTH_SUPPORT */
|
---|
152 |
|
---|
153 | return ppp;
|
---|
154 |
|
---|
155 | ppp_new_failed:
|
---|
156 | udp_remove(udp);
|
---|
157 | udp_new_failed:
|
---|
158 | LWIP_MEMPOOL_FREE(PPPOL2TP_PCB, l2tp);
|
---|
159 | memp_malloc_l2tp_failed:
|
---|
160 | ipaddr_check_failed:
|
---|
161 | return NULL;
|
---|
162 | }
|
---|
163 |
|
---|
164 | /* Called by PPP core */
|
---|
165 | static err_t pppol2tp_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) {
|
---|
166 | pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
|
---|
167 | struct pbuf *ph; /* UDP + L2TP header */
|
---|
168 | err_t ret;
|
---|
169 | #if MIB2_STATS
|
---|
170 | u16_t tot_len;
|
---|
171 | #else /* MIB2_STATS */
|
---|
172 | LWIP_UNUSED_ARG(ppp);
|
---|
173 | #endif /* MIB2_STATS */
|
---|
174 |
|
---|
175 | ph = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(PPPOL2TP_OUTPUT_DATA_HEADER_LEN), PBUF_RAM);
|
---|
176 | if(!ph) {
|
---|
177 | LINK_STATS_INC(link.memerr);
|
---|
178 | LINK_STATS_INC(link.proterr);
|
---|
179 | MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
|
---|
180 | pbuf_free(p);
|
---|
181 | return ERR_MEM;
|
---|
182 | }
|
---|
183 |
|
---|
184 | pbuf_remove_header(ph, PPPOL2TP_OUTPUT_DATA_HEADER_LEN); /* hide L2TP header */
|
---|
185 | pbuf_cat(ph, p);
|
---|
186 | #if MIB2_STATS
|
---|
187 | tot_len = ph->tot_len;
|
---|
188 | #endif /* MIB2_STATS */
|
---|
189 |
|
---|
190 | ret = pppol2tp_xmit(l2tp, ph);
|
---|
191 | if (ret != ERR_OK) {
|
---|
192 | LINK_STATS_INC(link.err);
|
---|
193 | MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
|
---|
194 | return ret;
|
---|
195 | }
|
---|
196 |
|
---|
197 | MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, (u16_t)tot_len);
|
---|
198 | MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts);
|
---|
199 | LINK_STATS_INC(link.xmit);
|
---|
200 | return ERR_OK;
|
---|
201 | }
|
---|
202 |
|
---|
203 | /* Called by PPP core */
|
---|
204 | static err_t pppol2tp_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol) {
|
---|
205 | pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
|
---|
206 | struct pbuf *pb;
|
---|
207 | u8_t *pl;
|
---|
208 | err_t err;
|
---|
209 | #if MIB2_STATS
|
---|
210 | u16_t tot_len;
|
---|
211 | #else /* MIB2_STATS */
|
---|
212 | LWIP_UNUSED_ARG(ppp);
|
---|
213 | #endif /* MIB2_STATS */
|
---|
214 |
|
---|
215 | /* @todo: try to use pbuf_header() here! */
|
---|
216 | pb = pbuf_alloc(PBUF_TRANSPORT, PPPOL2TP_OUTPUT_DATA_HEADER_LEN + sizeof(protocol), PBUF_RAM);
|
---|
217 | if(!pb) {
|
---|
218 | LINK_STATS_INC(link.memerr);
|
---|
219 | LINK_STATS_INC(link.proterr);
|
---|
220 | MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
|
---|
221 | return ERR_MEM;
|
---|
222 | }
|
---|
223 |
|
---|
224 | pbuf_remove_header(pb, PPPOL2TP_OUTPUT_DATA_HEADER_LEN);
|
---|
225 |
|
---|
226 | pl = (u8_t*)pb->payload;
|
---|
227 | PUTSHORT(protocol, pl);
|
---|
228 |
|
---|
229 | pbuf_chain(pb, p);
|
---|
230 | #if MIB2_STATS
|
---|
231 | tot_len = pb->tot_len;
|
---|
232 | #endif /* MIB2_STATS */
|
---|
233 |
|
---|
234 | if( (err = pppol2tp_xmit(l2tp, pb)) != ERR_OK) {
|
---|
235 | LINK_STATS_INC(link.err);
|
---|
236 | MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
|
---|
237 | return err;
|
---|
238 | }
|
---|
239 |
|
---|
240 | MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, tot_len);
|
---|
241 | MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts);
|
---|
242 | LINK_STATS_INC(link.xmit);
|
---|
243 | return ERR_OK;
|
---|
244 | }
|
---|
245 |
|
---|
246 | /* Destroy a L2TP control block */
|
---|
247 | static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx) {
|
---|
248 | pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
|
---|
249 | LWIP_UNUSED_ARG(ppp);
|
---|
250 |
|
---|
251 | sys_untimeout(pppol2tp_timeout, l2tp);
|
---|
252 | udp_remove(l2tp->udp);
|
---|
253 | LWIP_MEMPOOL_FREE(PPPOL2TP_PCB, l2tp);
|
---|
254 | return ERR_OK;
|
---|
255 | }
|
---|
256 |
|
---|
257 | /* Be a LAC, connect to a LNS. */
|
---|
258 | static void pppol2tp_connect(ppp_pcb *ppp, void *ctx) {
|
---|
259 | err_t err;
|
---|
260 | pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
|
---|
261 | lcp_options *lcp_wo;
|
---|
262 | lcp_options *lcp_ao;
|
---|
263 | #if PPP_IPV4_SUPPORT && VJ_SUPPORT
|
---|
264 | ipcp_options *ipcp_wo;
|
---|
265 | ipcp_options *ipcp_ao;
|
---|
266 | #endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */
|
---|
267 |
|
---|
268 | l2tp->tunnel_port = l2tp->remote_port;
|
---|
269 | l2tp->our_ns = 0;
|
---|
270 | l2tp->peer_nr = 0;
|
---|
271 | l2tp->peer_ns = 0;
|
---|
272 | l2tp->source_tunnel_id = 0;
|
---|
273 | l2tp->remote_tunnel_id = 0;
|
---|
274 | l2tp->source_session_id = 0;
|
---|
275 | l2tp->remote_session_id = 0;
|
---|
276 | /* l2tp->*_retried are cleared when used */
|
---|
277 |
|
---|
278 | lcp_wo = &ppp->lcp_wantoptions;
|
---|
279 | lcp_wo->mru = PPPOL2TP_DEFMRU;
|
---|
280 | lcp_wo->neg_asyncmap = 0;
|
---|
281 | lcp_wo->neg_pcompression = 0;
|
---|
282 | lcp_wo->neg_accompression = 0;
|
---|
283 | lcp_wo->passive = 0;
|
---|
284 | lcp_wo->silent = 0;
|
---|
285 |
|
---|
286 | lcp_ao = &ppp->lcp_allowoptions;
|
---|
287 | lcp_ao->mru = PPPOL2TP_DEFMRU;
|
---|
288 | lcp_ao->neg_asyncmap = 0;
|
---|
289 | lcp_ao->neg_pcompression = 0;
|
---|
290 | lcp_ao->neg_accompression = 0;
|
---|
291 |
|
---|
292 | #if PPP_IPV4_SUPPORT && VJ_SUPPORT
|
---|
293 | ipcp_wo = &ppp->ipcp_wantoptions;
|
---|
294 | ipcp_wo->neg_vj = 0;
|
---|
295 | ipcp_wo->old_vj = 0;
|
---|
296 |
|
---|
297 | ipcp_ao = &ppp->ipcp_allowoptions;
|
---|
298 | ipcp_ao->neg_vj = 0;
|
---|
299 | ipcp_ao->old_vj = 0;
|
---|
300 | #endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */
|
---|
301 |
|
---|
302 | /* Listen to a random source port, we need to do that instead of using udp_connect()
|
---|
303 | * because the L2TP LNS might answer with its own random source port (!= 1701)
|
---|
304 | */
|
---|
305 | #if LWIP_IPV6
|
---|
306 | if (IP_IS_V6_VAL(l2tp->udp->local_ip)) {
|
---|
307 | udp_bind(l2tp->udp, IP6_ADDR_ANY, 0);
|
---|
308 | } else
|
---|
309 | #endif /* LWIP_IPV6 */
|
---|
310 | udp_bind(l2tp->udp, IP_ADDR_ANY, 0);
|
---|
311 |
|
---|
312 | #if PPPOL2TP_AUTH_SUPPORT
|
---|
313 | /* Generate random vector */
|
---|
314 | if (l2tp->secret != NULL) {
|
---|
315 | magic_random_bytes(l2tp->secret_rv, sizeof(l2tp->secret_rv));
|
---|
316 | }
|
---|
317 | #endif /* PPPOL2TP_AUTH_SUPPORT */
|
---|
318 |
|
---|
319 | do {
|
---|
320 | l2tp->remote_tunnel_id = magic();
|
---|
321 | } while(l2tp->remote_tunnel_id == 0);
|
---|
322 | /* save state, in case we fail to send SCCRQ */
|
---|
323 | l2tp->sccrq_retried = 0;
|
---|
324 | l2tp->phase = PPPOL2TP_STATE_SCCRQ_SENT;
|
---|
325 | if ((err = pppol2tp_send_sccrq(l2tp)) != 0) {
|
---|
326 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err));
|
---|
327 | }
|
---|
328 | sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
|
---|
329 | }
|
---|
330 |
|
---|
331 | /* Disconnect */
|
---|
332 | static void pppol2tp_disconnect(ppp_pcb *ppp, void *ctx) {
|
---|
333 | pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
|
---|
334 |
|
---|
335 | l2tp->our_ns++;
|
---|
336 | pppol2tp_send_stopccn(l2tp, l2tp->our_ns);
|
---|
337 |
|
---|
338 | /* stop any timer, disconnect can be called while initiating is in progress */
|
---|
339 | sys_untimeout(pppol2tp_timeout, l2tp);
|
---|
340 | l2tp->phase = PPPOL2TP_STATE_INITIAL;
|
---|
341 | ppp_link_end(ppp); /* notify upper layers */
|
---|
342 | }
|
---|
343 |
|
---|
344 | /* UDP Callback for incoming IPv4 L2TP frames */
|
---|
345 | static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) {
|
---|
346 | pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg;
|
---|
347 | u16_t hflags, hlen, len=0, tunnel_id=0, session_id=0, ns=0, nr=0, offset=0;
|
---|
348 | u8_t *inp;
|
---|
349 | LWIP_UNUSED_ARG(pcb);
|
---|
350 |
|
---|
351 | /* we can't unbound a UDP pcb, thus we can still receive UDP frames after the link is closed */
|
---|
352 | if (l2tp->phase < PPPOL2TP_STATE_SCCRQ_SENT) {
|
---|
353 | goto free_and_return;
|
---|
354 | }
|
---|
355 |
|
---|
356 | if (!ip_addr_cmp(&l2tp->remote_ip, addr)) {
|
---|
357 | goto free_and_return;
|
---|
358 | }
|
---|
359 |
|
---|
360 | /* discard packet if port mismatch, but only if we received a SCCRP */
|
---|
361 | if (l2tp->phase > PPPOL2TP_STATE_SCCRQ_SENT && l2tp->tunnel_port != port) {
|
---|
362 | goto free_and_return;
|
---|
363 | }
|
---|
364 |
|
---|
365 | /* printf("-----------\nL2TP INPUT, %d\n", p->len); */
|
---|
366 |
|
---|
367 | /* L2TP header */
|
---|
368 | if (p->len < sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id) ) {
|
---|
369 | goto packet_too_short;
|
---|
370 | }
|
---|
371 |
|
---|
372 | inp = (u8_t*)p->payload;
|
---|
373 | GETSHORT(hflags, inp);
|
---|
374 |
|
---|
375 | if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) {
|
---|
376 | /* check mandatory flags for a control packet */
|
---|
377 | if ( (hflags & PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY) != PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY ) {
|
---|
378 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for control packet not set\n"));
|
---|
379 | goto free_and_return;
|
---|
380 | }
|
---|
381 | /* check forbidden flags for a control packet */
|
---|
382 | if (hflags & PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN) {
|
---|
383 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: forbidden header flags for control packet found\n"));
|
---|
384 | goto free_and_return;
|
---|
385 | }
|
---|
386 | } else {
|
---|
387 | /* check mandatory flags for a data packet */
|
---|
388 | if ( (hflags & PPPOL2TP_HEADERFLAG_DATA_MANDATORY) != PPPOL2TP_HEADERFLAG_DATA_MANDATORY) {
|
---|
389 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for data packet not set\n"));
|
---|
390 | goto free_and_return;
|
---|
391 | }
|
---|
392 | }
|
---|
393 |
|
---|
394 | /* Expected header size */
|
---|
395 | hlen = sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id);
|
---|
396 | if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) {
|
---|
397 | hlen += sizeof(len);
|
---|
398 | }
|
---|
399 | if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) {
|
---|
400 | hlen += sizeof(ns) + sizeof(nr);
|
---|
401 | }
|
---|
402 | if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) {
|
---|
403 | hlen += sizeof(offset);
|
---|
404 | }
|
---|
405 | if (p->len < hlen) {
|
---|
406 | goto packet_too_short;
|
---|
407 | }
|
---|
408 |
|
---|
409 | if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) {
|
---|
410 | GETSHORT(len, inp);
|
---|
411 | if (p->len < len || len < hlen) {
|
---|
412 | goto packet_too_short;
|
---|
413 | }
|
---|
414 | }
|
---|
415 | GETSHORT(tunnel_id, inp);
|
---|
416 | GETSHORT(session_id, inp);
|
---|
417 | if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) {
|
---|
418 | GETSHORT(ns, inp);
|
---|
419 | GETSHORT(nr, inp);
|
---|
420 | }
|
---|
421 | if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) {
|
---|
422 | GETSHORT(offset, inp)
|
---|
423 | if (offset > 4096) { /* don't be fooled with large offset which might overflow hlen */
|
---|
424 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: strange packet received, offset=%d\n", offset));
|
---|
425 | goto free_and_return;
|
---|
426 | }
|
---|
427 | hlen += offset;
|
---|
428 | if (p->len < hlen) {
|
---|
429 | goto packet_too_short;
|
---|
430 | }
|
---|
431 | INCPTR(offset, inp);
|
---|
432 | }
|
---|
433 |
|
---|
434 | /* printf("HLEN = %d\n", hlen); */
|
---|
435 |
|
---|
436 | /* skip L2TP header */
|
---|
437 | if (pbuf_remove_header(p, hlen) != 0) {
|
---|
438 | goto free_and_return;
|
---|
439 | }
|
---|
440 |
|
---|
441 | /* printf("LEN=%d, TUNNEL_ID=%d, SESSION_ID=%d, NS=%d, NR=%d, OFFSET=%d\n", len, tunnel_id, session_id, ns, nr, offset); */
|
---|
442 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: input packet, len=%"U16_F", tunnel=%"U16_F", session=%"U16_F", ns=%"U16_F", nr=%"U16_F"\n",
|
---|
443 | len, tunnel_id, session_id, ns, nr));
|
---|
444 |
|
---|
445 | /* Control packet */
|
---|
446 | if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) {
|
---|
447 | pppol2tp_dispatch_control_packet(l2tp, port, p, ns, nr);
|
---|
448 | goto free_and_return;
|
---|
449 | }
|
---|
450 |
|
---|
451 | /* Data packet */
|
---|
452 | if(l2tp->phase != PPPOL2TP_STATE_DATA) {
|
---|
453 | goto free_and_return;
|
---|
454 | }
|
---|
455 | if(tunnel_id != l2tp->remote_tunnel_id) {
|
---|
456 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: tunnel ID mismatch, assigned=%d, received=%d\n", l2tp->remote_tunnel_id, tunnel_id));
|
---|
457 | goto free_and_return;
|
---|
458 | }
|
---|
459 | if(session_id != l2tp->remote_session_id) {
|
---|
460 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: session ID mismatch, assigned=%d, received=%d\n", l2tp->remote_session_id, session_id));
|
---|
461 | goto free_and_return;
|
---|
462 | }
|
---|
463 | /*
|
---|
464 | * skip address & flags if necessary
|
---|
465 | *
|
---|
466 | * RFC 2661 does not specify whether the PPP frame in the L2TP payload should
|
---|
467 | * have a HDLC header or not. We handle both cases for compatibility.
|
---|
468 | */
|
---|
469 | if (p->len >= 2) {
|
---|
470 | GETSHORT(hflags, inp);
|
---|
471 | if (hflags == 0xff03) {
|
---|
472 | pbuf_remove_header(p, 2);
|
---|
473 | }
|
---|
474 | }
|
---|
475 | /* Dispatch the packet thereby consuming it. */
|
---|
476 | ppp_input(l2tp->ppp, p);
|
---|
477 | return;
|
---|
478 |
|
---|
479 | packet_too_short:
|
---|
480 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len));
|
---|
481 | free_and_return:
|
---|
482 | pbuf_free(p);
|
---|
483 | }
|
---|
484 |
|
---|
485 | /* L2TP Control packet entry point */
|
---|
486 | static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, struct pbuf *p, u16_t ns, u16_t nr) {
|
---|
487 | u8_t *inp;
|
---|
488 | u16_t avplen, avpflags, vendorid, attributetype, messagetype=0;
|
---|
489 | err_t err;
|
---|
490 | #if PPPOL2TP_AUTH_SUPPORT
|
---|
491 | lwip_md5_context md5_ctx;
|
---|
492 | u8_t md5_hash[16];
|
---|
493 | u8_t challenge_id = 0;
|
---|
494 | #endif /* PPPOL2TP_AUTH_SUPPORT */
|
---|
495 |
|
---|
496 | /* printf("L2TP CTRL INPUT, ns=%d, nr=%d, len=%d\n", ns, nr, p->len); */
|
---|
497 |
|
---|
498 | /* Drop unexpected packet */
|
---|
499 | if (ns != l2tp->peer_ns) {
|
---|
500 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: drop unexpected packet: received NS=%d, expected NS=%d\n", ns, l2tp->peer_ns));
|
---|
501 | /*
|
---|
502 | * In order to ensure that all messages are acknowledged properly
|
---|
503 | * (particularly in the case of a lost ZLB ACK message), receipt
|
---|
504 | * of duplicate messages MUST be acknowledged.
|
---|
505 | *
|
---|
506 | * In this very special case we Ack a packet we previously received.
|
---|
507 | * Therefore our NS is the NR we just received. And our NR is the
|
---|
508 | * NS we just received plus one.
|
---|
509 | */
|
---|
510 | if ((s16_t)(ns - l2tp->peer_ns) < 0) {
|
---|
511 | pppol2tp_send_zlb(l2tp, nr, ns+1);
|
---|
512 | }
|
---|
513 | return;
|
---|
514 | }
|
---|
515 |
|
---|
516 | l2tp->peer_nr = nr;
|
---|
517 |
|
---|
518 | /* Handle the special case of the ICCN acknowledge */
|
---|
519 | if (l2tp->phase == PPPOL2TP_STATE_ICCN_SENT && (s16_t)(l2tp->peer_nr - l2tp->our_ns) > 0) {
|
---|
520 | l2tp->phase = PPPOL2TP_STATE_DATA;
|
---|
521 | sys_untimeout(pppol2tp_timeout, l2tp);
|
---|
522 | ppp_start(l2tp->ppp); /* notify upper layers */
|
---|
523 | }
|
---|
524 |
|
---|
525 | /* ZLB packets */
|
---|
526 | if (p->tot_len == 0) {
|
---|
527 | return;
|
---|
528 | }
|
---|
529 | /* A ZLB packet does not consume a NS slot thus we don't record the NS value for ZLB packets */
|
---|
530 | l2tp->peer_ns = ns+1;
|
---|
531 |
|
---|
532 | p = pbuf_coalesce(p, PBUF_RAW);
|
---|
533 | inp = (u8_t*)p->payload;
|
---|
534 | /* Decode AVPs */
|
---|
535 | while (p->len > 0) {
|
---|
536 | if (p->len < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype) ) {
|
---|
537 | goto packet_too_short;
|
---|
538 | }
|
---|
539 | GETSHORT(avpflags, inp);
|
---|
540 | avplen = avpflags & PPPOL2TP_AVPHEADERFLAG_LENGTHMASK;
|
---|
541 | /* printf("AVPLEN = %d\n", avplen); */
|
---|
542 | if (p->len < avplen || avplen < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) {
|
---|
543 | goto packet_too_short;
|
---|
544 | }
|
---|
545 | GETSHORT(vendorid, inp);
|
---|
546 | GETSHORT(attributetype, inp);
|
---|
547 | avplen -= sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype);
|
---|
548 |
|
---|
549 | /* Message type must be the first AVP */
|
---|
550 | if (messagetype == 0) {
|
---|
551 | if (attributetype != 0 || vendorid != 0 || avplen != sizeof(messagetype) ) {
|
---|
552 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: message type must be the first AVP\n"));
|
---|
553 | return;
|
---|
554 | }
|
---|
555 | GETSHORT(messagetype, inp);
|
---|
556 | /* printf("Message type = %d\n", messagetype); */
|
---|
557 | switch(messagetype) {
|
---|
558 | /* Start Control Connection Reply */
|
---|
559 | case PPPOL2TP_MESSAGETYPE_SCCRP:
|
---|
560 | /* Only accept SCCRP packet if we sent a SCCRQ */
|
---|
561 | if (l2tp->phase != PPPOL2TP_STATE_SCCRQ_SENT) {
|
---|
562 | goto send_zlb;
|
---|
563 | }
|
---|
564 | break;
|
---|
565 | /* Incoming Call Reply */
|
---|
566 | case PPPOL2TP_MESSAGETYPE_ICRP:
|
---|
567 | /* Only accept ICRP packet if we sent a IRCQ */
|
---|
568 | if (l2tp->phase != PPPOL2TP_STATE_ICRQ_SENT) {
|
---|
569 | goto send_zlb;
|
---|
570 | }
|
---|
571 | break;
|
---|
572 | /* Stop Control Connection Notification */
|
---|
573 | case PPPOL2TP_MESSAGETYPE_STOPCCN:
|
---|
574 | pppol2tp_send_zlb(l2tp, l2tp->our_ns+1, l2tp->peer_ns); /* Ack the StopCCN before we switch to down state */
|
---|
575 | if (l2tp->phase < PPPOL2TP_STATE_DATA) {
|
---|
576 | pppol2tp_abort_connect(l2tp);
|
---|
577 | } else if (l2tp->phase == PPPOL2TP_STATE_DATA) {
|
---|
578 | /* Don't disconnect here, we let the LCP Echo/Reply find the fact
|
---|
579 | * that PPP session is down. Asking the PPP stack to end the session
|
---|
580 | * require strict checking about the PPP phase to prevent endless
|
---|
581 | * disconnection loops.
|
---|
582 | */
|
---|
583 | }
|
---|
584 | return;
|
---|
585 | default:
|
---|
586 | break;
|
---|
587 | }
|
---|
588 | goto nextavp;
|
---|
589 | }
|
---|
590 |
|
---|
591 | /* Skip proprietary L2TP extensions */
|
---|
592 | if (vendorid != 0) {
|
---|
593 | goto skipavp;
|
---|
594 | }
|
---|
595 |
|
---|
596 | switch (messagetype) {
|
---|
597 | /* Start Control Connection Reply */
|
---|
598 | case PPPOL2TP_MESSAGETYPE_SCCRP:
|
---|
599 | switch (attributetype) {
|
---|
600 | case PPPOL2TP_AVPTYPE_TUNNELID:
|
---|
601 | if (avplen != sizeof(l2tp->source_tunnel_id) ) {
|
---|
602 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign tunnel ID length check failed\n"));
|
---|
603 | return;
|
---|
604 | }
|
---|
605 | GETSHORT(l2tp->source_tunnel_id, inp);
|
---|
606 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned tunnel ID %"U16_F"\n", l2tp->source_tunnel_id));
|
---|
607 | goto nextavp;
|
---|
608 | #if PPPOL2TP_AUTH_SUPPORT
|
---|
609 | case PPPOL2TP_AVPTYPE_CHALLENGE:
|
---|
610 | if (avplen == 0) {
|
---|
611 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: Challenge length check failed\n"));
|
---|
612 | return;
|
---|
613 | }
|
---|
614 | if (l2tp->secret == NULL) {
|
---|
615 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge from peer and no secret key available\n"));
|
---|
616 | pppol2tp_abort_connect(l2tp);
|
---|
617 | return;
|
---|
618 | }
|
---|
619 | /* Generate hash of ID, secret, challenge */
|
---|
620 | lwip_md5_init(&md5_ctx);
|
---|
621 | lwip_md5_starts(&md5_ctx);
|
---|
622 | challenge_id = PPPOL2TP_MESSAGETYPE_SCCCN;
|
---|
623 | lwip_md5_update(&md5_ctx, &challenge_id, 1);
|
---|
624 | lwip_md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len);
|
---|
625 | lwip_md5_update(&md5_ctx, inp, avplen);
|
---|
626 | lwip_md5_finish(&md5_ctx, l2tp->challenge_hash);
|
---|
627 | lwip_md5_free(&md5_ctx);
|
---|
628 | l2tp->send_challenge = 1;
|
---|
629 | goto skipavp;
|
---|
630 | case PPPOL2TP_AVPTYPE_CHALLENGERESPONSE:
|
---|
631 | if (avplen != PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE) {
|
---|
632 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Challenge Response length check failed\n"));
|
---|
633 | return;
|
---|
634 | }
|
---|
635 | /* Generate hash of ID, secret, challenge */
|
---|
636 | lwip_md5_init(&md5_ctx);
|
---|
637 | lwip_md5_starts(&md5_ctx);
|
---|
638 | challenge_id = PPPOL2TP_MESSAGETYPE_SCCRP;
|
---|
639 | lwip_md5_update(&md5_ctx, &challenge_id, 1);
|
---|
640 | lwip_md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len);
|
---|
641 | lwip_md5_update(&md5_ctx, l2tp->secret_rv, sizeof(l2tp->secret_rv));
|
---|
642 | lwip_md5_finish(&md5_ctx, md5_hash);
|
---|
643 | lwip_md5_free(&md5_ctx);
|
---|
644 | if ( memcmp(inp, md5_hash, sizeof(md5_hash)) ) {
|
---|
645 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge response from peer and secret key do not match\n"));
|
---|
646 | pppol2tp_abort_connect(l2tp);
|
---|
647 | return;
|
---|
648 | }
|
---|
649 | goto skipavp;
|
---|
650 | #endif /* PPPOL2TP_AUTH_SUPPORT */
|
---|
651 | default:
|
---|
652 | break;
|
---|
653 | }
|
---|
654 | break;
|
---|
655 | /* Incoming Call Reply */
|
---|
656 | case PPPOL2TP_MESSAGETYPE_ICRP:
|
---|
657 | switch (attributetype) {
|
---|
658 | case PPPOL2TP_AVPTYPE_SESSIONID:
|
---|
659 | if (avplen != sizeof(l2tp->source_session_id) ) {
|
---|
660 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign session ID length check failed\n"));
|
---|
661 | return;
|
---|
662 | }
|
---|
663 | GETSHORT(l2tp->source_session_id, inp);
|
---|
664 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned session ID %"U16_F"\n", l2tp->source_session_id));
|
---|
665 | goto nextavp;
|
---|
666 | default:
|
---|
667 | break;
|
---|
668 | }
|
---|
669 | break;
|
---|
670 | default:
|
---|
671 | break;
|
---|
672 | }
|
---|
673 |
|
---|
674 | skipavp:
|
---|
675 | INCPTR(avplen, inp);
|
---|
676 | nextavp:
|
---|
677 | /* printf("AVP Found, vendor=%d, attribute=%d, len=%d\n", vendorid, attributetype, avplen); */
|
---|
678 | /* next AVP */
|
---|
679 | if (pbuf_remove_header(p, avplen + sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) != 0) {
|
---|
680 | return;
|
---|
681 | }
|
---|
682 | }
|
---|
683 |
|
---|
684 | switch(messagetype) {
|
---|
685 | /* Start Control Connection Reply */
|
---|
686 | case PPPOL2TP_MESSAGETYPE_SCCRP:
|
---|
687 | do {
|
---|
688 | l2tp->remote_session_id = magic();
|
---|
689 | } while(l2tp->remote_session_id == 0);
|
---|
690 | l2tp->tunnel_port = port; /* LNS server might have chosen its own local port */
|
---|
691 | l2tp->icrq_retried = 0;
|
---|
692 | l2tp->phase = PPPOL2TP_STATE_ICRQ_SENT;
|
---|
693 | l2tp->our_ns++;
|
---|
694 | if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns)) != 0) {
|
---|
695 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err));
|
---|
696 | LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
|
---|
697 | }
|
---|
698 | l2tp->our_ns++;
|
---|
699 | if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) {
|
---|
700 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err));
|
---|
701 | LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
|
---|
702 | }
|
---|
703 | sys_untimeout(pppol2tp_timeout, l2tp);
|
---|
704 | sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
|
---|
705 | break;
|
---|
706 | /* Incoming Call Reply */
|
---|
707 | case PPPOL2TP_MESSAGETYPE_ICRP:
|
---|
708 | l2tp->iccn_retried = 0;
|
---|
709 | l2tp->phase = PPPOL2TP_STATE_ICCN_SENT;
|
---|
710 | l2tp->our_ns++;
|
---|
711 | if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) {
|
---|
712 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err));
|
---|
713 | LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
|
---|
714 | }
|
---|
715 | sys_untimeout(pppol2tp_timeout, l2tp);
|
---|
716 | sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
|
---|
717 | break;
|
---|
718 | /* Unhandled packet, send ZLB ACK */
|
---|
719 | default:
|
---|
720 | goto send_zlb;
|
---|
721 | }
|
---|
722 | return;
|
---|
723 |
|
---|
724 | send_zlb:
|
---|
725 | pppol2tp_send_zlb(l2tp, l2tp->our_ns+1, l2tp->peer_ns);
|
---|
726 | return;
|
---|
727 | packet_too_short:
|
---|
728 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len));
|
---|
729 | }
|
---|
730 |
|
---|
731 | /* L2TP Timeout handler */
|
---|
732 | static void pppol2tp_timeout(void *arg) {
|
---|
733 | pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg;
|
---|
734 | err_t err;
|
---|
735 | u32_t retry_wait;
|
---|
736 |
|
---|
737 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: timeout\n"));
|
---|
738 |
|
---|
739 | switch (l2tp->phase) {
|
---|
740 | case PPPOL2TP_STATE_SCCRQ_SENT:
|
---|
741 | /* backoff wait */
|
---|
742 | if (l2tp->sccrq_retried < 0xff) {
|
---|
743 | l2tp->sccrq_retried++;
|
---|
744 | }
|
---|
745 | if (!l2tp->ppp->settings.persist && l2tp->sccrq_retried >= PPPOL2TP_MAXSCCRQ) {
|
---|
746 | pppol2tp_abort_connect(l2tp);
|
---|
747 | return;
|
---|
748 | }
|
---|
749 | retry_wait = LWIP_MIN(PPPOL2TP_CONTROL_TIMEOUT * l2tp->sccrq_retried, PPPOL2TP_SLOW_RETRY);
|
---|
750 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: sccrq_retried=%d\n", l2tp->sccrq_retried));
|
---|
751 | if ((err = pppol2tp_send_sccrq(l2tp)) != 0) {
|
---|
752 | l2tp->sccrq_retried--;
|
---|
753 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err));
|
---|
754 | LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
|
---|
755 | }
|
---|
756 | sys_timeout(retry_wait, pppol2tp_timeout, l2tp);
|
---|
757 | break;
|
---|
758 |
|
---|
759 | case PPPOL2TP_STATE_ICRQ_SENT:
|
---|
760 | l2tp->icrq_retried++;
|
---|
761 | if (l2tp->icrq_retried >= PPPOL2TP_MAXICRQ) {
|
---|
762 | pppol2tp_abort_connect(l2tp);
|
---|
763 | return;
|
---|
764 | }
|
---|
765 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: icrq_retried=%d\n", l2tp->icrq_retried));
|
---|
766 | if ((s16_t)(l2tp->peer_nr - l2tp->our_ns) < 0) { /* the SCCCN was not acknowledged */
|
---|
767 | if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns -1)) != 0) {
|
---|
768 | l2tp->icrq_retried--;
|
---|
769 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err));
|
---|
770 | LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
|
---|
771 | sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
|
---|
772 | break;
|
---|
773 | }
|
---|
774 | }
|
---|
775 | if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) {
|
---|
776 | l2tp->icrq_retried--;
|
---|
777 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err));
|
---|
778 | LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
|
---|
779 | }
|
---|
780 | sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
|
---|
781 | break;
|
---|
782 |
|
---|
783 | case PPPOL2TP_STATE_ICCN_SENT:
|
---|
784 | l2tp->iccn_retried++;
|
---|
785 | if (l2tp->iccn_retried >= PPPOL2TP_MAXICCN) {
|
---|
786 | pppol2tp_abort_connect(l2tp);
|
---|
787 | return;
|
---|
788 | }
|
---|
789 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: iccn_retried=%d\n", l2tp->iccn_retried));
|
---|
790 | if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) {
|
---|
791 | l2tp->iccn_retried--;
|
---|
792 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err));
|
---|
793 | LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */
|
---|
794 | }
|
---|
795 | sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
|
---|
796 | break;
|
---|
797 |
|
---|
798 | default:
|
---|
799 | return; /* all done, work in peace */
|
---|
800 | }
|
---|
801 | }
|
---|
802 |
|
---|
803 | /* Connection attempt aborted */
|
---|
804 | static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp) {
|
---|
805 | PPPDEBUG(LOG_DEBUG, ("pppol2tp: could not establish connection\n"));
|
---|
806 | l2tp->phase = PPPOL2TP_STATE_INITIAL;
|
---|
807 | ppp_link_failed(l2tp->ppp); /* notify upper layers */
|
---|
808 | }
|
---|
809 |
|
---|
810 | /* Initiate a new tunnel */
|
---|
811 | static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp) {
|
---|
812 | struct pbuf *pb;
|
---|
813 | u8_t *p;
|
---|
814 | u16_t len;
|
---|
815 |
|
---|
816 | /* calculate UDP packet length */
|
---|
817 | len = 12 +8 +8 +10 +10 +6+sizeof(PPPOL2TP_HOSTNAME)-1 +6+sizeof(PPPOL2TP_VENDORNAME)-1 +8 +8;
|
---|
818 | #if PPPOL2TP_AUTH_SUPPORT
|
---|
819 | if (l2tp->secret != NULL) {
|
---|
820 | len += 6 + sizeof(l2tp->secret_rv);
|
---|
821 | }
|
---|
822 | #endif /* PPPOL2TP_AUTH_SUPPORT */
|
---|
823 |
|
---|
824 | /* allocate a buffer */
|
---|
825 | pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
|
---|
826 | if (pb == NULL) {
|
---|
827 | return ERR_MEM;
|
---|
828 | }
|
---|
829 | LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
---|
830 |
|
---|
831 | p = (u8_t*)pb->payload;
|
---|
832 | /* fill in pkt */
|
---|
833 | /* L2TP control header */
|
---|
834 | PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
|
---|
835 | PUTSHORT(len, p); /* Length */
|
---|
836 | PUTSHORT(0, p); /* Tunnel Id */
|
---|
837 | PUTSHORT(0, p); /* Session Id */
|
---|
838 | PUTSHORT(0, p); /* NS Sequence number - to peer */
|
---|
839 | PUTSHORT(0, p); /* NR Sequence number - expected for peer */
|
---|
840 |
|
---|
841 | /* AVP - Message type */
|
---|
842 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
843 | PUTSHORT(0, p); /* Vendor ID */
|
---|
844 | PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
|
---|
845 | PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCRQ, p); /* Attribute value: Message type: SCCRQ */
|
---|
846 |
|
---|
847 | /* AVP - L2TP Version */
|
---|
848 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
849 | PUTSHORT(0, p); /* Vendor ID */
|
---|
850 | PUTSHORT(PPPOL2TP_AVPTYPE_VERSION, p); /* Attribute type: Version */
|
---|
851 | PUTSHORT(PPPOL2TP_VERSION, p); /* Attribute value: L2TP Version */
|
---|
852 |
|
---|
853 | /* AVP - Framing capabilities */
|
---|
854 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
|
---|
855 | PUTSHORT(0, p); /* Vendor ID */
|
---|
856 | PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES, p); /* Attribute type: Framing capabilities */
|
---|
857 | PUTLONG(PPPOL2TP_FRAMINGCAPABILITIES, p); /* Attribute value: Framing capabilities */
|
---|
858 |
|
---|
859 | /* AVP - Bearer capabilities */
|
---|
860 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
|
---|
861 | PUTSHORT(0, p); /* Vendor ID */
|
---|
862 | PUTSHORT(PPPOL2TP_AVPTYPE_BEARERCAPABILITIES, p); /* Attribute type: Bearer capabilities */
|
---|
863 | PUTLONG(PPPOL2TP_BEARERCAPABILITIES, p); /* Attribute value: Bearer capabilities */
|
---|
864 |
|
---|
865 | /* AVP - Host name */
|
---|
866 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6+sizeof(PPPOL2TP_HOSTNAME)-1, p); /* Mandatory flag + len field */
|
---|
867 | PUTSHORT(0, p); /* Vendor ID */
|
---|
868 | PUTSHORT(PPPOL2TP_AVPTYPE_HOSTNAME, p); /* Attribute type: Hostname */
|
---|
869 | MEMCPY(p, PPPOL2TP_HOSTNAME, sizeof(PPPOL2TP_HOSTNAME)-1); /* Attribute value: Hostname */
|
---|
870 | INCPTR(sizeof(PPPOL2TP_HOSTNAME)-1, p);
|
---|
871 |
|
---|
872 | /* AVP - Vendor name */
|
---|
873 | PUTSHORT(6+sizeof(PPPOL2TP_VENDORNAME)-1, p); /* len field */
|
---|
874 | PUTSHORT(0, p); /* Vendor ID */
|
---|
875 | PUTSHORT(PPPOL2TP_AVPTYPE_VENDORNAME, p); /* Attribute type: Vendor name */
|
---|
876 | MEMCPY(p, PPPOL2TP_VENDORNAME, sizeof(PPPOL2TP_VENDORNAME)-1); /* Attribute value: Vendor name */
|
---|
877 | INCPTR(sizeof(PPPOL2TP_VENDORNAME)-1, p);
|
---|
878 |
|
---|
879 | /* AVP - Assign tunnel ID */
|
---|
880 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
881 | PUTSHORT(0, p); /* Vendor ID */
|
---|
882 | PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */
|
---|
883 | PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */
|
---|
884 |
|
---|
885 | /* AVP - Receive window size */
|
---|
886 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
887 | PUTSHORT(0, p); /* Vendor ID */
|
---|
888 | PUTSHORT(PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE, p); /* Attribute type: Receive window size */
|
---|
889 | PUTSHORT(PPPOL2TP_RECEIVEWINDOWSIZE, p); /* Attribute value: Receive window size */
|
---|
890 |
|
---|
891 | #if PPPOL2TP_AUTH_SUPPORT
|
---|
892 | /* AVP - Challenge */
|
---|
893 | if (l2tp->secret != NULL) {
|
---|
894 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->secret_rv), p); /* Mandatory flag + len field */
|
---|
895 | PUTSHORT(0, p); /* Vendor ID */
|
---|
896 | PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGE, p); /* Attribute type: Challenge */
|
---|
897 | MEMCPY(p, l2tp->secret_rv, sizeof(l2tp->secret_rv)); /* Attribute value: Random vector */
|
---|
898 | INCPTR(sizeof(l2tp->secret_rv), p);
|
---|
899 | }
|
---|
900 | #endif /* PPPOL2TP_AUTH_SUPPORT */
|
---|
901 |
|
---|
902 | return pppol2tp_udp_send(l2tp, pb);
|
---|
903 | }
|
---|
904 |
|
---|
905 | /* Complete tunnel establishment */
|
---|
906 | static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns) {
|
---|
907 | struct pbuf *pb;
|
---|
908 | u8_t *p;
|
---|
909 | u16_t len;
|
---|
910 |
|
---|
911 | /* calculate UDP packet length */
|
---|
912 | len = 12 +8;
|
---|
913 | #if PPPOL2TP_AUTH_SUPPORT
|
---|
914 | if (l2tp->send_challenge) {
|
---|
915 | len += 6 + sizeof(l2tp->challenge_hash);
|
---|
916 | }
|
---|
917 | #endif /* PPPOL2TP_AUTH_SUPPORT */
|
---|
918 |
|
---|
919 | /* allocate a buffer */
|
---|
920 | pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
|
---|
921 | if (pb == NULL) {
|
---|
922 | return ERR_MEM;
|
---|
923 | }
|
---|
924 | LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
---|
925 |
|
---|
926 | p = (u8_t*)pb->payload;
|
---|
927 | /* fill in pkt */
|
---|
928 | /* L2TP control header */
|
---|
929 | PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
|
---|
930 | PUTSHORT(len, p); /* Length */
|
---|
931 | PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
|
---|
932 | PUTSHORT(0, p); /* Session Id */
|
---|
933 | PUTSHORT(ns, p); /* NS Sequence number - to peer */
|
---|
934 | PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */
|
---|
935 |
|
---|
936 | /* AVP - Message type */
|
---|
937 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
938 | PUTSHORT(0, p); /* Vendor ID */
|
---|
939 | PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
|
---|
940 | PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCCN, p); /* Attribute value: Message type: SCCCN */
|
---|
941 |
|
---|
942 | #if PPPOL2TP_AUTH_SUPPORT
|
---|
943 | /* AVP - Challenge response */
|
---|
944 | if (l2tp->send_challenge) {
|
---|
945 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->challenge_hash), p); /* Mandatory flag + len field */
|
---|
946 | PUTSHORT(0, p); /* Vendor ID */
|
---|
947 | PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGERESPONSE, p); /* Attribute type: Challenge response */
|
---|
948 | MEMCPY(p, l2tp->challenge_hash, sizeof(l2tp->challenge_hash)); /* Attribute value: Computed challenge */
|
---|
949 | INCPTR(sizeof(l2tp->challenge_hash), p);
|
---|
950 | }
|
---|
951 | #endif /* PPPOL2TP_AUTH_SUPPORT */
|
---|
952 |
|
---|
953 | return pppol2tp_udp_send(l2tp, pb);
|
---|
954 | }
|
---|
955 |
|
---|
956 | /* Initiate a new session */
|
---|
957 | static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns) {
|
---|
958 | struct pbuf *pb;
|
---|
959 | u8_t *p;
|
---|
960 | u16_t len;
|
---|
961 | u32_t serialnumber;
|
---|
962 |
|
---|
963 | /* calculate UDP packet length */
|
---|
964 | len = 12 +8 +8 +10;
|
---|
965 |
|
---|
966 | /* allocate a buffer */
|
---|
967 | pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
|
---|
968 | if (pb == NULL) {
|
---|
969 | return ERR_MEM;
|
---|
970 | }
|
---|
971 | LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
---|
972 |
|
---|
973 | p = (u8_t*)pb->payload;
|
---|
974 | /* fill in pkt */
|
---|
975 | /* L2TP control header */
|
---|
976 | PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
|
---|
977 | PUTSHORT(len, p); /* Length */
|
---|
978 | PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
|
---|
979 | PUTSHORT(0, p); /* Session Id */
|
---|
980 | PUTSHORT(ns, p); /* NS Sequence number - to peer */
|
---|
981 | PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */
|
---|
982 |
|
---|
983 | /* AVP - Message type */
|
---|
984 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
985 | PUTSHORT(0, p); /* Vendor ID */
|
---|
986 | PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
|
---|
987 | PUTSHORT(PPPOL2TP_MESSAGETYPE_ICRQ, p); /* Attribute value: Message type: ICRQ */
|
---|
988 |
|
---|
989 | /* AVP - Assign session ID */
|
---|
990 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
991 | PUTSHORT(0, p); /* Vendor ID */
|
---|
992 | PUTSHORT(PPPOL2TP_AVPTYPE_SESSIONID, p); /* Attribute type: Session ID */
|
---|
993 | PUTSHORT(l2tp->remote_session_id, p); /* Attribute value: Session ID */
|
---|
994 |
|
---|
995 | /* AVP - Call Serial Number */
|
---|
996 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
|
---|
997 | PUTSHORT(0, p); /* Vendor ID */
|
---|
998 | PUTSHORT(PPPOL2TP_AVPTYPE_CALLSERIALNUMBER, p); /* Attribute type: Serial number */
|
---|
999 | serialnumber = magic();
|
---|
1000 | PUTLONG(serialnumber, p); /* Attribute value: Serial number */
|
---|
1001 |
|
---|
1002 | return pppol2tp_udp_send(l2tp, pb);
|
---|
1003 | }
|
---|
1004 |
|
---|
1005 | /* Complete tunnel establishment */
|
---|
1006 | static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns) {
|
---|
1007 | struct pbuf *pb;
|
---|
1008 | u8_t *p;
|
---|
1009 | u16_t len;
|
---|
1010 |
|
---|
1011 | /* calculate UDP packet length */
|
---|
1012 | len = 12 +8 +10 +10;
|
---|
1013 |
|
---|
1014 | /* allocate a buffer */
|
---|
1015 | pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
|
---|
1016 | if (pb == NULL) {
|
---|
1017 | return ERR_MEM;
|
---|
1018 | }
|
---|
1019 | LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
---|
1020 |
|
---|
1021 | p = (u8_t*)pb->payload;
|
---|
1022 | /* fill in pkt */
|
---|
1023 | /* L2TP control header */
|
---|
1024 | PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
|
---|
1025 | PUTSHORT(len, p); /* Length */
|
---|
1026 | PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
|
---|
1027 | PUTSHORT(l2tp->source_session_id, p); /* Session Id */
|
---|
1028 | PUTSHORT(ns, p); /* NS Sequence number - to peer */
|
---|
1029 | PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */
|
---|
1030 |
|
---|
1031 | /* AVP - Message type */
|
---|
1032 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
1033 | PUTSHORT(0, p); /* Vendor ID */
|
---|
1034 | PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
|
---|
1035 | PUTSHORT(PPPOL2TP_MESSAGETYPE_ICCN, p); /* Attribute value: Message type: ICCN */
|
---|
1036 |
|
---|
1037 | /* AVP - Framing type */
|
---|
1038 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
|
---|
1039 | PUTSHORT(0, p); /* Vendor ID */
|
---|
1040 | PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGTYPE, p); /* Attribute type: Framing type */
|
---|
1041 | PUTLONG(PPPOL2TP_FRAMINGTYPE, p); /* Attribute value: Framing type */
|
---|
1042 |
|
---|
1043 | /* AVP - TX Connect speed */
|
---|
1044 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */
|
---|
1045 | PUTSHORT(0, p); /* Vendor ID */
|
---|
1046 | PUTSHORT(PPPOL2TP_AVPTYPE_TXCONNECTSPEED, p); /* Attribute type: TX Connect speed */
|
---|
1047 | PUTLONG(PPPOL2TP_TXCONNECTSPEED, p); /* Attribute value: TX Connect speed */
|
---|
1048 |
|
---|
1049 | return pppol2tp_udp_send(l2tp, pb);
|
---|
1050 | }
|
---|
1051 |
|
---|
1052 | /* Send a ZLB ACK packet */
|
---|
1053 | static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns, u16_t nr) {
|
---|
1054 | struct pbuf *pb;
|
---|
1055 | u8_t *p;
|
---|
1056 | u16_t len;
|
---|
1057 |
|
---|
1058 | /* calculate UDP packet length */
|
---|
1059 | len = 12;
|
---|
1060 |
|
---|
1061 | /* allocate a buffer */
|
---|
1062 | pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
|
---|
1063 | if (pb == NULL) {
|
---|
1064 | return ERR_MEM;
|
---|
1065 | }
|
---|
1066 | LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
---|
1067 |
|
---|
1068 | p = (u8_t*)pb->payload;
|
---|
1069 | /* fill in pkt */
|
---|
1070 | /* L2TP control header */
|
---|
1071 | PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
|
---|
1072 | PUTSHORT(len, p); /* Length */
|
---|
1073 | PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
|
---|
1074 | PUTSHORT(0, p); /* Session Id */
|
---|
1075 | PUTSHORT(ns, p); /* NS Sequence number - to peer */
|
---|
1076 | PUTSHORT(nr, p); /* NR Sequence number - expected for peer */
|
---|
1077 |
|
---|
1078 | return pppol2tp_udp_send(l2tp, pb);
|
---|
1079 | }
|
---|
1080 |
|
---|
1081 | /* Send a StopCCN packet */
|
---|
1082 | static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns) {
|
---|
1083 | struct pbuf *pb;
|
---|
1084 | u8_t *p;
|
---|
1085 | u16_t len;
|
---|
1086 |
|
---|
1087 | /* calculate UDP packet length */
|
---|
1088 | len = 12 +8 +8 +8;
|
---|
1089 |
|
---|
1090 | /* allocate a buffer */
|
---|
1091 | pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
|
---|
1092 | if (pb == NULL) {
|
---|
1093 | return ERR_MEM;
|
---|
1094 | }
|
---|
1095 | LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
---|
1096 |
|
---|
1097 | p = (u8_t*)pb->payload;
|
---|
1098 | /* fill in pkt */
|
---|
1099 | /* L2TP control header */
|
---|
1100 | PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p);
|
---|
1101 | PUTSHORT(len, p); /* Length */
|
---|
1102 | PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
|
---|
1103 | PUTSHORT(0, p); /* Session Id */
|
---|
1104 | PUTSHORT(ns, p); /* NS Sequence number - to peer */
|
---|
1105 | PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */
|
---|
1106 |
|
---|
1107 | /* AVP - Message type */
|
---|
1108 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
1109 | PUTSHORT(0, p); /* Vendor ID */
|
---|
1110 | PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */
|
---|
1111 | PUTSHORT(PPPOL2TP_MESSAGETYPE_STOPCCN, p); /* Attribute value: Message type: StopCCN */
|
---|
1112 |
|
---|
1113 | /* AVP - Assign tunnel ID */
|
---|
1114 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
1115 | PUTSHORT(0, p); /* Vendor ID */
|
---|
1116 | PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */
|
---|
1117 | PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */
|
---|
1118 |
|
---|
1119 | /* AVP - Result code */
|
---|
1120 | PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */
|
---|
1121 | PUTSHORT(0, p); /* Vendor ID */
|
---|
1122 | PUTSHORT(PPPOL2TP_AVPTYPE_RESULTCODE, p); /* Attribute type: Result code */
|
---|
1123 | PUTSHORT(PPPOL2TP_RESULTCODE, p); /* Attribute value: Result code */
|
---|
1124 |
|
---|
1125 | return pppol2tp_udp_send(l2tp, pb);
|
---|
1126 | }
|
---|
1127 |
|
---|
1128 | static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb) {
|
---|
1129 | u8_t *p;
|
---|
1130 |
|
---|
1131 | /* make room for L2TP header - should not fail */
|
---|
1132 | if (pbuf_add_header(pb, PPPOL2TP_OUTPUT_DATA_HEADER_LEN) != 0) {
|
---|
1133 | /* bail out */
|
---|
1134 | PPPDEBUG(LOG_ERR, ("pppol2tp: pppol2tp_pcb: could not allocate room for L2TP header\n"));
|
---|
1135 | LINK_STATS_INC(link.lenerr);
|
---|
1136 | pbuf_free(pb);
|
---|
1137 | return ERR_BUF;
|
---|
1138 | }
|
---|
1139 |
|
---|
1140 | p = (u8_t*)pb->payload;
|
---|
1141 | PUTSHORT(PPPOL2TP_HEADERFLAG_DATA_MANDATORY, p);
|
---|
1142 | PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
|
---|
1143 | PUTSHORT(l2tp->source_session_id, p); /* Session Id */
|
---|
1144 |
|
---|
1145 | return pppol2tp_udp_send(l2tp, pb);
|
---|
1146 | }
|
---|
1147 |
|
---|
1148 | static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb) {
|
---|
1149 | err_t err;
|
---|
1150 | if (l2tp->netif) {
|
---|
1151 | err = udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port, l2tp->netif);
|
---|
1152 | } else {
|
---|
1153 | err = udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port);
|
---|
1154 | }
|
---|
1155 | pbuf_free(pb);
|
---|
1156 | return err;
|
---|
1157 | }
|
---|
1158 |
|
---|
1159 | #endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */
|
---|