blob: 6b1e1de0a21c9c3273cfd0c177eccdd293e0dd2d [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 *
50 * $Id: ipcp.c,v 1.1 2004/08/20 12:29:54 oliverschmidt Exp $
51 *
52 */
53
54/* */
55/* include files */
56/* */
57
58#define DEBUG1(x) printf x
59
60#include "uip.h"
61/*#include "time.h"*/
62#include "ipcp.h"
63#include "ppp.h"
64#include "ahdlc.h"
65
66#define TIMER_expire()
67#define TIMER_set()
68#define TIMER_timeout(x) 1
69
70#ifdef IPCP_GET_PEER_IP
71uip_ipaddr_t peer_ip_addr;
72#endif
73
74#ifdef IPCP_GET_PRI_DNS
75uip_ipaddr_t pri_dns_addr;
76#endif
77
78#ifdef IPCP_GET_SEC_DNS
79uip_ipaddr_t sec_dns_addr;
80#endif
81
82/*
83 * Local IPCP state
84 */
85u8_t ipcp_state;
86
87/*
88 * in the future add copression protocol and name servers (possibly for servers only)
89 */
90u8_t ipcplist[] = {0x3, 0};
91
92/*---------------------------------------------------------------------------*/
93/*void
94printip(uip_ipaddr_t ip)
95{
96DEBUG1((" %d.%d.%d.%d ",ip.ipb1,ip.ip8[1],ip.ip8[2],ip.ip8[3]));
97 }*/
98#define printip(x)
99/*---------------------------------------------------------------------------*/
100void
101ipcp_init(void)
102{
103 DEBUG1(("ipcp init\n"));
104 ipcp_state = 0;
105 ppp_retry = 0;
106 our_ipaddr.ip16[0] = our_ipaddr.ip16[1] = 0;
107}
108/*---------------------------------------------------------------------------*/
109/*
110 * IPCP RX protocol Handler
111 */
112void
113ipcp_rx(u8_t *buffer, u16_t count)
114{
115 u8_t *bptr = buffer;
116 IPCPPKT *pkt=(IPCPPKT *)buffer;
117 u16_t len;
118
119 DEBUG1(("IPCP len %d\n",count));
120
121 switch(*bptr++) {
122 case CONF_REQ:
123 /* parce request and see if we can ACK it */
124 ++bptr;
125 len = (*bptr++ << 8);
126 len |= *bptr++;
127 /* len-=2; */
128
129 DEBUG1(("check lcplist\n"));
130 if(scan_packet(IPCP, ipcplist, buffer, bptr, (u16_t)(len - 4))) {
131 DEBUG1(("option was bad\n"));
132 } else {
133 DEBUG1(("IPCP options are good\n"));
134 /*
135 * Parse out the results
136 */
137 /* lets try to implement what peer wants */
138 /* Reject any protocol not */
139 /* Error? if we we need to send a config Reject ++++ this is
140 good for a subroutine*/
141 /* All we should get is the peer IP address */
142 if(IPCP_IPADDRESS == *bptr++) {
143 /* dump length */
144 ++bptr;
145#ifdef IPCP_GET_PEER_IP
146 peer_ip_addr.ip8[0] = *bptr++;
147 peer_ip_addr.ip8[1] = *bptr++;
148 peer_ip_addr.ip8[2] = *bptr++;
149 peer_ip_addr.ip8[3] = *bptr++;
150 DEBUG1(("Peer IP "));
151 /* printip(peer_ip_addr);*/
152 DEBUG1(("\n"));
153#else
154 bptr += 4;
155#endif
156 } else {
157 DEBUG1(("HMMMM this shouldn't happen IPCP1\n"));
158 }
159
160#if 0
161 if(error) {
162 /* write the config NAK packet we've built above, take on the header */
163 bptr = buffer;
164 *bptr++ = CONF_NAK; /* Write Conf_rej */
165 *bptr++;
166 /*tptr++;*/ /* skip over ID */
167
168 /* Write new length */
169 *bptr++ = 0;
170 *bptr = tptr - buffer;
171
172 /* write the reject frame */
173 DEBUG1(("Writing NAK frame \n"));
174 ahdlc_tx(IPCP, buffer, (u16_t)(tptr - buffer));
175 DEBUG1(("- End NAK Write frame\n"));
176
177 } else {
178 }
179#endif
180 /*
181 * If we get here then we are OK, lets send an ACK and tell the rest
182 * of our modules our negotiated config.
183 */
184 ipcp_state |= IPCP_RX_UP;
185 DEBUG1(("Send IPCP ACK!\n"));
186 bptr = buffer;
187 *bptr++ = CONF_ACK; /* Write Conf_ACK */
188 bptr++; /* Skip ID (send same one) */
189 /*
190 * Set stuff
191 */
192 /* ppp_flags |= tflag; */
193 DEBUG1(("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer)));
194
195 /* write the ACK frame */
196 DEBUG1(("Writing ACK frame \n"));
197 /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */
198 ahdlc_tx(IPCP, 0, buffer, 0, count /*bptr-buffer*/);
199 DEBUG1(("- End ACK Write frame\n"));
200
201 /* expire the timer to make things happen after a state change */
202 /*timer_expire(); */
203
204 /* } */
205 }
206 break;
207 case CONF_ACK: /* config Ack */
208 DEBUG1(("CONF ACK\n"));
209 /*
210 * Parse out the results
211 *
212 * Dump the ID and get the length.
213 */
214 /* dump the ID */
215 bptr++;
216
217 /* get the length */
218 len = (*bptr++ << 8);
219 len |= *bptr++;
220#if 0
221 /* Parse ACK and set data */
222 while(bptr < buffer + len) {
223 switch(*bptr++) {
224 case IPCP_IPADDRESS:
225 /* dump length */
226 bptr++;
227 ipaddr.ip8[0] = *bptr++;
228 ipaddr.ip8[1] = *bptr++;
229 ipaddr.ip8[2] = *bptr++;
230 ipaddr.ip8[3] = *bptr++;
231 break;
232 case IPCP_PRIMARY_DNS:
233 bptr++;
234 pri_dns_addr.ip8[0] = *bptr++;
235 pri_dns_addr.ip8[1] = *bptr++;
236 pri_dns_addr.ip8[2] = *bptr++;
237 pri_dns_addr.ip8[3] = *bptr++;
238 break;
239 case IPCP_SECONDARY_DNS:
240 bptr++;
241 sec_dns_addr.ip8[0] = *bptr++;
242 sec_dns_addr.ip8[1] = *bptr++;
243 sec_dns_addr.ip8[2] = *bptr++;
244 sec_dns_addr.ip8[3] = *bptr++;
245 break;
246 default:
247 DEBUG1(("IPCP CONFIG_ACK problem1\n"));
248 }
249 }
250#endif
251 ipcp_state |= IPCP_TX_UP;
252 /*ipcp_state &= ~IPCP_RX_UP;*/
253 DEBUG1(("were up! \n"));
254 printip(our_ipaddr);
255#ifdef IPCP_GET_PRI_DNS
256 printip(pri_dns_addr);
257#endif
258#ifdef IPCP_GET_SEC_DNS
259 printip(sec_dns_addr);
260#endif
261 DEBUG1(("\n"));
262
263 /* expire the timer to make things happen after a state change */
264 TIMER_expire();
265 break;
266 case CONF_NAK: /* Config Nack */
267 DEBUG1(("CONF NAK\n"));
268 /* dump the ID */
269 bptr++;
270 /* get the length */
271 len = (*bptr++ << 8);
272 len |= *bptr++;
273
274 /* Parse ACK and set data */
275 while(bptr < buffer + len) {
276 switch(*bptr++) {
277 case IPCP_IPADDRESS:
278 /* dump length */
279 bptr++;
280 our_ipaddr.ip8[0] = *bptr++;
281 our_ipaddr.ip8[1] = *bptr++;
282 our_ipaddr.ip8[2] = *bptr++;
283 our_ipaddr.ip8[3] = *bptr++;
284 break;
285#ifdef IPCP_GET_PRI_DNS
286 case IPCP_PRIMARY_DNS:
287 bptr++;
288 pri_dns_addr.ip8[0] = *bptr++;
289 pri_dns_addr.ip8[1] = *bptr++;
290 pri_dns_addr.ip8[2] = *bptr++;
291 pri_dns_addr.ip8[3] = *bptr++;
292 break;
293#endif
294#ifdef IPCP_GET_SEC_DNS
295 case IPCP_SECONDARY_DNS:
296 bptr++;
297 sec_dns_addr.ip8[0] = *bptr++;
298 sec_dns_addr.ip8[1] = *bptr++;
299 sec_dns_addr.ip8[2] = *bptr++;
300 sec_dns_addr.ip8[3] = *bptr++;
301 break;
302#endif
303 default:
304 DEBUG1(("IPCP CONFIG_ACK problem 2\n"));
305 }
306 }
307 ppp_id++;
308 printip(our_ipaddr);
309#ifdef IPCP_GET_PRI_DNS
310 printip(pri_dns_addr);
311#endif
312#ifdef IPCP_GET_PRI_DNS
313 printip(sec_dns_addr);
314#endif
315 DEBUG1(("\n"));
316 /* expire the timer to make things happen after a state change */
317 TIMER_expire();
318 break;
319 case CONF_REJ: /* Config Reject */
320 DEBUG1(("CONF REJ\n"));
321 /* Remove the offending options*/
322 ppp_id++;
323 /* dump the ID */
324 bptr++;
325 /* get the length */
326 len = (*bptr++ << 8);
327 len |= *bptr++;
328
329 /* Parse ACK and set data */
330 while(bptr < buffer + len) {
331 switch(*bptr++) {
332 case IPCP_IPADDRESS:
333 ipcp_state |= IPCP_IP_BIT;
334 bptr += 5;
335 break;
336#ifdef IPCP_GET_PRI_DNS
337 case IPCP_PRIMARY_DNS:
338 ipcp_state |= IPCP_PRI_DNS_BIT;
339 bptr += 5;
340 break;
341#endif
342#ifdef IPCP_GET_PRI_DNS
343 case IPCP_SECONDARY_DNS:
344 ipcp_state |= IPCP_SEC_DNS_BIT;
345 bptr += 5;
346 break;
347#endif
348 default:
349 DEBUG1(("IPCP this shoudln't happen 3\n"));
350 }
351 }
352 /* expire the timer to make things happen after a state change */
353 /*timer_expire(); */
354 break;
355 default:
356 DEBUG1(("-Unknown 4\n"));
357 }
358}
359
360/*---------------------------------------------------------------------------*/
361void
362ipcp_task(u8_t *buffer)
363{
364 u8_t *bptr;
365 u16_t t;
366 IPCPPKT *pkt;
367
368 /* IPCP tx not up and hasn't timed out then lets see if we need to
369 send a request */
370 if(!(ipcp_state & IPCP_TX_UP) && !(ipcp_state & IPCP_TX_TIMEOUT)) {
371 /* Check if we have a request pending */
372 /*t=get_seconds()-ipcp_tx_time;*/
373 if(TIMER_timeout(IPCP_TIMEOUT)) {
374 /*
375 * No pending request, lets build one
376 */
377 pkt=(IPCPPKT *)buffer;
378
379 /* Configure-Request only here, write id */
380 pkt->code = CONF_REQ;
381 pkt->id = ppp_id;
382
383 bptr = pkt->data;
384
385 /*
386 * Write options, we want IP address, and DNS addresses if set.
387 */
388
389 /* Write zeros for IP address the first time */
390 *bptr++ = IPCP_IPADDRESS;
391 *bptr++ = 0x6;
392 *bptr++ = our_ipaddr.ip8[0];
393 *bptr++ = our_ipaddr.ip8[1];
394 *bptr++ = our_ipaddr.ip8[2];
395 *bptr++ = our_ipaddr.ip8[3];
396
397#ifdef IPCP_GET_PRI_DNS
398 if(!(ipcp_state & IPCP_PRI_DNS_BIT)) {
399 /* Write zeros for IP address the first time */
400 *bptr++ = IPCP_PRIMARY_DNS;
401 *bptr++ = 0x6;
402 *bptr++ = pri_dns_addr.ip8[0];
403 *bptr++ = pri_dns_addr.ip8[1];
404 *bptr++ = pri_dns_addr.ip8[2];
405 *bptr++ = pri_dns_addr.ip8[3];
406 }
407#endif
408#ifdef IPCP_GET_SEC_DNS
409 if(!(ipcp_state & IPCP_SEC_DNS_BIT)) {
410 /* Write zeros for IP address the first time */
411 *bptr++ = IPCP_SECONDARY_DNS;
412 *bptr++ = 0x6;
413 *bptr++ = sec_dns_addr.ip8[0];
414 *bptr++ = sec_dns_addr.ip8[1];
415 *bptr++ = sec_dns_addr.ip8[2];
416 *bptr++ = sec_dns_addr.ip8[3];
417 }
418#endif
419 /* Write length */
420 t = bptr - buffer;
421 /* length here - code and ID + */
422 pkt->len = htons(t);
423
424 DEBUG1(("\n**Sending IPCP Request packet\n"));
425
426 /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */
427 ahdlc_tx(IPCP, 0, buffer, 0, t);
428
429 /* Set timer */
430 /*ipcp_tx_time=get_seconds();*/
431 TIMER_set();
432 /* Inc retry */
433 /*ipcp_retry++;*/
434 ppp_retry++;
435 /*
436 * Have we timed out? (combide the timers?)
437 */
438 if(ppp_retry > IPCP_RETRY_COUNT)
439 ipcp_state &= IPCP_TX_TIMEOUT;
440 }
441 }
442}
443/*---------------------------------------------------------------------------*/