blob: 2a2f812ad0e3d8f37d11581b2de008e3edacda25 [file] [log] [blame]
oliverschmidt3396e9a2004-08-20 12:29:54 +00001/*
2 *---------------------------------------------------------------------------
3 * ipcp.c - PPP IPCP (intrnet protocol) Processor/Handler
4 *
5 *---------------------------------------------------------------------------
6 *
7 * Version
8 * 0.1 Original Version Jun 3, 2000
9 *
10 *---------------------------------------------------------------------------
11 *
12 * Copyright (C) 2000, Mycal Labs www.mycal.com
13 *
14 *---------------------------------------------------------------------------
15 */
16/*
17 * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * 3. All advertising materials mentioning features or use of this software
29 * must display the following acknowledgement:
30 * This product includes software developed by Mike Johnson/Mycal Labs
31 * www.mycal.net.
32 * 4. The name of the author may not be used to endorse or promote
33 * products derived from this software without specific prior
34 * written permission.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
37 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
40 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 *
48 * This file is part of the Mycal Modified uIP TCP/IP stack.
49 *
oliverschmidt85729cb2005-01-26 23:36:22 +000050 * $Id: ipcp.c,v 1.3 2005/01/26 23:36:22 oliverschmidt Exp $
oliverschmidt3396e9a2004-08-20 12:29:54 +000051 *
52 */
53
54/* */
55/* include files */
56/* */
57
oliverschmidt85729cb2005-01-26 23:36:22 +000058#if 0
oliverschmidtacc63952004-08-29 15:11:45 +000059#define DEBUG1(x)
60#else
61#include <stdio.h>
oliverschmidt85729cb2005-01-26 23:36:22 +000062#define DEBUG1(x) debug_printf x
oliverschmidtacc63952004-08-29 15:11:45 +000063#endif
oliverschmidt3396e9a2004-08-20 12:29:54 +000064
65#include "uip.h"
66/*#include "time.h"*/
67#include "ipcp.h"
68#include "ppp.h"
69#include "ahdlc.h"
70
71#define TIMER_expire()
72#define TIMER_set()
73#define TIMER_timeout(x) 1
74
75#ifdef IPCP_GET_PEER_IP
76uip_ipaddr_t peer_ip_addr;
77#endif
78
79#ifdef IPCP_GET_PRI_DNS
80uip_ipaddr_t pri_dns_addr;
81#endif
82
83#ifdef IPCP_GET_SEC_DNS
84uip_ipaddr_t sec_dns_addr;
85#endif
86
87/*
88 * Local IPCP state
89 */
90u8_t ipcp_state;
91
92/*
93 * in the future add copression protocol and name servers (possibly for servers only)
94 */
95u8_t ipcplist[] = {0x3, 0};
96
97/*---------------------------------------------------------------------------*/
98/*void
99printip(uip_ipaddr_t ip)
100{
101DEBUG1((" %d.%d.%d.%d ",ip.ipb1,ip.ip8[1],ip.ip8[2],ip.ip8[3]));
102 }*/
103#define printip(x)
104/*---------------------------------------------------------------------------*/
105void
106ipcp_init(void)
107{
108 DEBUG1(("ipcp init\n"));
109 ipcp_state = 0;
110 ppp_retry = 0;
111 our_ipaddr.ip16[0] = our_ipaddr.ip16[1] = 0;
112}
113/*---------------------------------------------------------------------------*/
114/*
115 * IPCP RX protocol Handler
116 */
117void
118ipcp_rx(u8_t *buffer, u16_t count)
119{
120 u8_t *bptr = buffer;
121 IPCPPKT *pkt=(IPCPPKT *)buffer;
122 u16_t len;
123
124 DEBUG1(("IPCP len %d\n",count));
125
126 switch(*bptr++) {
127 case CONF_REQ:
128 /* parce request and see if we can ACK it */
129 ++bptr;
130 len = (*bptr++ << 8);
131 len |= *bptr++;
132 /* len-=2; */
133
134 DEBUG1(("check lcplist\n"));
135 if(scan_packet(IPCP, ipcplist, buffer, bptr, (u16_t)(len - 4))) {
136 DEBUG1(("option was bad\n"));
137 } else {
138 DEBUG1(("IPCP options are good\n"));
139 /*
140 * Parse out the results
141 */
142 /* lets try to implement what peer wants */
143 /* Reject any protocol not */
144 /* Error? if we we need to send a config Reject ++++ this is
145 good for a subroutine*/
146 /* All we should get is the peer IP address */
147 if(IPCP_IPADDRESS == *bptr++) {
148 /* dump length */
149 ++bptr;
150#ifdef IPCP_GET_PEER_IP
151 peer_ip_addr.ip8[0] = *bptr++;
152 peer_ip_addr.ip8[1] = *bptr++;
153 peer_ip_addr.ip8[2] = *bptr++;
154 peer_ip_addr.ip8[3] = *bptr++;
155 DEBUG1(("Peer IP "));
156 /* printip(peer_ip_addr);*/
157 DEBUG1(("\n"));
158#else
159 bptr += 4;
160#endif
161 } else {
162 DEBUG1(("HMMMM this shouldn't happen IPCP1\n"));
163 }
164
165#if 0
166 if(error) {
167 /* write the config NAK packet we've built above, take on the header */
168 bptr = buffer;
169 *bptr++ = CONF_NAK; /* Write Conf_rej */
170 *bptr++;
171 /*tptr++;*/ /* skip over ID */
172
173 /* Write new length */
174 *bptr++ = 0;
175 *bptr = tptr - buffer;
176
177 /* write the reject frame */
178 DEBUG1(("Writing NAK frame \n"));
179 ahdlc_tx(IPCP, buffer, (u16_t)(tptr - buffer));
180 DEBUG1(("- End NAK Write frame\n"));
181
182 } else {
183 }
184#endif
185 /*
186 * If we get here then we are OK, lets send an ACK and tell the rest
187 * of our modules our negotiated config.
188 */
189 ipcp_state |= IPCP_RX_UP;
190 DEBUG1(("Send IPCP ACK!\n"));
191 bptr = buffer;
192 *bptr++ = CONF_ACK; /* Write Conf_ACK */
193 bptr++; /* Skip ID (send same one) */
194 /*
195 * Set stuff
196 */
197 /* ppp_flags |= tflag; */
198 DEBUG1(("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer)));
199
200 /* write the ACK frame */
201 DEBUG1(("Writing ACK frame \n"));
202 /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */
203 ahdlc_tx(IPCP, 0, buffer, 0, count /*bptr-buffer*/);
204 DEBUG1(("- End ACK Write frame\n"));
205
206 /* expire the timer to make things happen after a state change */
207 /*timer_expire(); */
208
209 /* } */
210 }
211 break;
212 case CONF_ACK: /* config Ack */
213 DEBUG1(("CONF ACK\n"));
214 /*
215 * Parse out the results
216 *
217 * Dump the ID and get the length.
218 */
219 /* dump the ID */
220 bptr++;
221
222 /* get the length */
223 len = (*bptr++ << 8);
224 len |= *bptr++;
225#if 0
226 /* Parse ACK and set data */
227 while(bptr < buffer + len) {
228 switch(*bptr++) {
229 case IPCP_IPADDRESS:
230 /* dump length */
231 bptr++;
232 ipaddr.ip8[0] = *bptr++;
233 ipaddr.ip8[1] = *bptr++;
234 ipaddr.ip8[2] = *bptr++;
235 ipaddr.ip8[3] = *bptr++;
236 break;
237 case IPCP_PRIMARY_DNS:
238 bptr++;
239 pri_dns_addr.ip8[0] = *bptr++;
240 pri_dns_addr.ip8[1] = *bptr++;
241 pri_dns_addr.ip8[2] = *bptr++;
242 pri_dns_addr.ip8[3] = *bptr++;
243 break;
244 case IPCP_SECONDARY_DNS:
245 bptr++;
246 sec_dns_addr.ip8[0] = *bptr++;
247 sec_dns_addr.ip8[1] = *bptr++;
248 sec_dns_addr.ip8[2] = *bptr++;
249 sec_dns_addr.ip8[3] = *bptr++;
250 break;
251 default:
252 DEBUG1(("IPCP CONFIG_ACK problem1\n"));
253 }
254 }
255#endif
256 ipcp_state |= IPCP_TX_UP;
257 /*ipcp_state &= ~IPCP_RX_UP;*/
258 DEBUG1(("were up! \n"));
259 printip(our_ipaddr);
260#ifdef IPCP_GET_PRI_DNS
261 printip(pri_dns_addr);
262#endif
263#ifdef IPCP_GET_SEC_DNS
264 printip(sec_dns_addr);
265#endif
266 DEBUG1(("\n"));
267
268 /* expire the timer to make things happen after a state change */
269 TIMER_expire();
270 break;
271 case CONF_NAK: /* Config Nack */
272 DEBUG1(("CONF NAK\n"));
273 /* dump the ID */
274 bptr++;
275 /* get the length */
276 len = (*bptr++ << 8);
277 len |= *bptr++;
278
279 /* Parse ACK and set data */
280 while(bptr < buffer + len) {
281 switch(*bptr++) {
282 case IPCP_IPADDRESS:
283 /* dump length */
284 bptr++;
285 our_ipaddr.ip8[0] = *bptr++;
286 our_ipaddr.ip8[1] = *bptr++;
287 our_ipaddr.ip8[2] = *bptr++;
288 our_ipaddr.ip8[3] = *bptr++;
289 break;
290#ifdef IPCP_GET_PRI_DNS
291 case IPCP_PRIMARY_DNS:
292 bptr++;
293 pri_dns_addr.ip8[0] = *bptr++;
294 pri_dns_addr.ip8[1] = *bptr++;
295 pri_dns_addr.ip8[2] = *bptr++;
296 pri_dns_addr.ip8[3] = *bptr++;
297 break;
298#endif
299#ifdef IPCP_GET_SEC_DNS
300 case IPCP_SECONDARY_DNS:
301 bptr++;
302 sec_dns_addr.ip8[0] = *bptr++;
303 sec_dns_addr.ip8[1] = *bptr++;
304 sec_dns_addr.ip8[2] = *bptr++;
305 sec_dns_addr.ip8[3] = *bptr++;
306 break;
307#endif
308 default:
309 DEBUG1(("IPCP CONFIG_ACK problem 2\n"));
310 }
311 }
312 ppp_id++;
313 printip(our_ipaddr);
314#ifdef IPCP_GET_PRI_DNS
315 printip(pri_dns_addr);
316#endif
317#ifdef IPCP_GET_PRI_DNS
318 printip(sec_dns_addr);
319#endif
320 DEBUG1(("\n"));
321 /* expire the timer to make things happen after a state change */
322 TIMER_expire();
323 break;
324 case CONF_REJ: /* Config Reject */
325 DEBUG1(("CONF REJ\n"));
326 /* Remove the offending options*/
327 ppp_id++;
328 /* dump the ID */
329 bptr++;
330 /* get the length */
331 len = (*bptr++ << 8);
332 len |= *bptr++;
333
334 /* Parse ACK and set data */
335 while(bptr < buffer + len) {
336 switch(*bptr++) {
337 case IPCP_IPADDRESS:
338 ipcp_state |= IPCP_IP_BIT;
339 bptr += 5;
340 break;
341#ifdef IPCP_GET_PRI_DNS
342 case IPCP_PRIMARY_DNS:
343 ipcp_state |= IPCP_PRI_DNS_BIT;
344 bptr += 5;
345 break;
346#endif
347#ifdef IPCP_GET_PRI_DNS
348 case IPCP_SECONDARY_DNS:
349 ipcp_state |= IPCP_SEC_DNS_BIT;
350 bptr += 5;
351 break;
352#endif
353 default:
354 DEBUG1(("IPCP this shoudln't happen 3\n"));
355 }
356 }
357 /* expire the timer to make things happen after a state change */
358 /*timer_expire(); */
359 break;
360 default:
361 DEBUG1(("-Unknown 4\n"));
362 }
363}
364
365/*---------------------------------------------------------------------------*/
366void
367ipcp_task(u8_t *buffer)
368{
369 u8_t *bptr;
370 u16_t t;
371 IPCPPKT *pkt;
372
373 /* IPCP tx not up and hasn't timed out then lets see if we need to
374 send a request */
375 if(!(ipcp_state & IPCP_TX_UP) && !(ipcp_state & IPCP_TX_TIMEOUT)) {
376 /* Check if we have a request pending */
377 /*t=get_seconds()-ipcp_tx_time;*/
378 if(TIMER_timeout(IPCP_TIMEOUT)) {
379 /*
380 * No pending request, lets build one
381 */
382 pkt=(IPCPPKT *)buffer;
383
384 /* Configure-Request only here, write id */
385 pkt->code = CONF_REQ;
386 pkt->id = ppp_id;
387
388 bptr = pkt->data;
389
390 /*
391 * Write options, we want IP address, and DNS addresses if set.
392 */
393
394 /* Write zeros for IP address the first time */
395 *bptr++ = IPCP_IPADDRESS;
396 *bptr++ = 0x6;
397 *bptr++ = our_ipaddr.ip8[0];
398 *bptr++ = our_ipaddr.ip8[1];
399 *bptr++ = our_ipaddr.ip8[2];
400 *bptr++ = our_ipaddr.ip8[3];
401
402#ifdef IPCP_GET_PRI_DNS
403 if(!(ipcp_state & IPCP_PRI_DNS_BIT)) {
404 /* Write zeros for IP address the first time */
405 *bptr++ = IPCP_PRIMARY_DNS;
406 *bptr++ = 0x6;
407 *bptr++ = pri_dns_addr.ip8[0];
408 *bptr++ = pri_dns_addr.ip8[1];
409 *bptr++ = pri_dns_addr.ip8[2];
410 *bptr++ = pri_dns_addr.ip8[3];
411 }
412#endif
413#ifdef IPCP_GET_SEC_DNS
414 if(!(ipcp_state & IPCP_SEC_DNS_BIT)) {
415 /* Write zeros for IP address the first time */
416 *bptr++ = IPCP_SECONDARY_DNS;
417 *bptr++ = 0x6;
418 *bptr++ = sec_dns_addr.ip8[0];
419 *bptr++ = sec_dns_addr.ip8[1];
420 *bptr++ = sec_dns_addr.ip8[2];
421 *bptr++ = sec_dns_addr.ip8[3];
422 }
423#endif
424 /* Write length */
425 t = bptr - buffer;
426 /* length here - code and ID + */
427 pkt->len = htons(t);
428
429 DEBUG1(("\n**Sending IPCP Request packet\n"));
430
431 /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */
432 ahdlc_tx(IPCP, 0, buffer, 0, t);
433
434 /* Set timer */
435 /*ipcp_tx_time=get_seconds();*/
436 TIMER_set();
437 /* Inc retry */
438 /*ipcp_retry++;*/
439 ppp_retry++;
440 /*
441 * Have we timed out? (combide the timers?)
442 */
443 if(ppp_retry > IPCP_RETRY_COUNT)
444 ipcp_state &= IPCP_TX_TIMEOUT;
445 }
446 }
447}
448/*---------------------------------------------------------------------------*/