OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [lwIP_Demo_Rowley_ARM7/] [lwip-1.1.0/] [src/] [core/] [ipv6/] [ip6.c] - Blame information for rev 583

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 583 jeremybenn
/*
2
 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without modification,
6
 * are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. The name of the author may not be used to endorse or promote products
14
 *    derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25
 * OF SUCH DAMAGE.
26
 *
27
 * This file is part of the lwIP TCP/IP stack.
28
 *
29
 * Author: Adam Dunkels <adam@sics.se>
30
 *
31
 */
32
 
33
 
34
 
35
/* ip.c
36
 *
37
 * This is the code for the IP layer for IPv6.
38
 *
39
 */
40
 
41
 
42
#include "lwip/opt.h"
43
 
44
#include "lwip/def.h"
45
#include "lwip/mem.h"
46
#include "lwip/ip.h"
47
#include "lwip/inet.h"
48
#include "lwip/netif.h"
49
#include "lwip/icmp.h"
50
#include "lwip/udp.h"
51
#include "lwip/tcp.h"
52
 
53
#include "lwip/stats.h"
54
 
55
#include "arch/perf.h"
56
 
57
/* ip_init:
58
 *
59
 * Initializes the IP layer.
60
 */
61
 
62
void
63
ip_init(void)
64
{
65
}
66
 
67
/* ip_route:
68
 *
69
 * Finds the appropriate network interface for a given IP address. It searches the
70
 * list of network interfaces linearly. A match is found if the masked IP address of
71
 * the network interface equals the masked IP address given to the function.
72
 */
73
 
74
struct netif *
75
ip_route(struct ip_addr *dest)
76
{
77
  struct netif *netif;
78
 
79
  for(netif = netif_list; netif != NULL; netif = netif->next) {
80
    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
81
      return netif;
82
    }
83
  }
84
 
85
  return netif_default;
86
}
87
 
88
/* ip_forward:
89
 *
90
 * Forwards an IP packet. It finds an appropriate route for the packet, decrements
91
 * the TTL value of the packet, adjusts the checksum and outputs the packet on the
92
 * appropriate interface.
93
 */
94
 
95
static void
96
ip_forward(struct pbuf *p, struct ip_hdr *iphdr)
97
{
98
  struct netif *netif;
99
 
100
  PERF_START;
101
 
102
  if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {
103
 
104
    LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));
105
#if IP_DEBUG
106
    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));
107
#endif /* IP_DEBUG */
108
    LWIP_DEBUGF(IP_DEBUG, ("\n"));
109
    pbuf_free(p);
110
    return;
111
  }
112
  /* Decrement TTL and send ICMP if ttl == 0. */
113
  if (--iphdr->hoplim == 0) {
114
    /* Don't send ICMP messages in response to ICMP messages */
115
    if (iphdr->nexthdr != IP_PROTO_ICMP) {
116
      icmp_time_exceeded(p, ICMP_TE_TTL);
117
    }
118
    pbuf_free(p);
119
    return;
120
  }
121
 
122
  /* Incremental update of the IP checksum. */
123
  /*  if (iphdr->chksum >= htons(0xffff - 0x100)) {
124
    iphdr->chksum += htons(0x100) + 1;
125
  } else {
126
    iphdr->chksum += htons(0x100);
127
    }*/
128
 
129
 
130
  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));
131
#if IP_DEBUG
132
  ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));
133
#endif /* IP_DEBUG */
134
  LWIP_DEBUGF(IP_DEBUG, ("\n"));
135
 
136
#ifdef IP_STATS
137
  ++lwip_stats.ip.fw;
138
  ++lwip_stats.ip.xmit;
139
#endif /* IP_STATS */
140
 
141
  PERF_STOP("ip_forward");
142
 
143
  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
144
}
145
 
146
/* ip_input:
147
 *
148
 * This function is called by the network interface device driver when an IP packet is
149
 * received. The function does the basic checks of the IP header such as packet size
150
 * being at least larger than the header size etc. If the packet was not destined for
151
 * us, the packet is forwarded (using ip_forward). The IP checksum is always checked.
152
 *
153
 * Finally, the packet is sent to the upper layer protocol input function.
154
 */
155
 
156
void
157
ip_input(struct pbuf *p, struct netif *inp) {
158
  struct ip_hdr *iphdr;
159
  struct netif *netif;
160
 
161
 
162
  PERF_START;
163
 
164
#if IP_DEBUG
165
  ip_debug_print(p);
166
#endif /* IP_DEBUG */
167
 
168
 
169
#ifdef IP_STATS
170
  ++lwip_stats.ip.recv;
171
#endif /* IP_STATS */
172
 
173
  /* identify the IP header */
174
  iphdr = p->payload;
175
 
176
 
177
  if (iphdr->v != 6) {
178
    LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));
179
#if IP_DEBUG
180
    ip_debug_print(p);
181
#endif /* IP_DEBUG */
182
    pbuf_free(p);
183
#ifdef IP_STATS
184
    ++lwip_stats.ip.err;
185
    ++lwip_stats.ip.drop;
186
#endif /* IP_STATS */
187
    return;
188
  }
189
 
190
  /* is this packet for us? */
191
  for(netif = netif_list; netif != NULL; netif = netif->next) {
192
#if IP_DEBUG
193
    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));
194
    ip_addr_debug_print(IP_DEBUG, &(iphdr->dest));
195
    LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr "));
196
    ip_addr_debug_print(IP_DEBUG, &(netif->ip_addr));
197
    LWIP_DEBUGF(IP_DEBUG, ("\n"));
198
#endif /* IP_DEBUG */
199
    if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {
200
      break;
201
    }
202
  }
203
 
204
 
205
  if (netif == NULL) {
206
    /* packet not for us, route or discard */
207
#ifdef IP_FORWARD
208
    ip_forward(p, iphdr);
209
#endif
210
    pbuf_free(p);
211
    return;
212
  }
213
 
214
  pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));
215
 
216
  /* send to upper layers */
217
#if IP_DEBUG
218
  /*  LWIP_DEBUGF("ip_input: \n");
219
  ip_debug_print(p);
220
  LWIP_DEBUGF("ip_input: p->len %u p->tot_len %u\n", p->len, p->tot_len);*/
221
#endif /* IP_DEBUG */
222
 
223
 
224
  pbuf_header(p, -IP_HLEN);
225
 
226
  switch (iphdr->nexthdr) {
227
  case IP_PROTO_UDP:
228
    udp_input(p);
229
    break;
230
  case IP_PROTO_TCP:
231
    tcp_input(p);
232
    break;
233
  case IP_PROTO_ICMP:
234
    icmp_input(p, inp);
235
    break;
236
  default:
237
    /* send ICMP destination protocol unreachable */
238
    icmp_dest_unreach(p, ICMP_DUR_PROTO);
239
    pbuf_free(p);
240
    LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %u\n",
241
          iphdr->nexthdr));
242
 
243
#ifdef IP_STATS
244
    ++lwip_stats.ip.proterr;
245
    ++lwip_stats.ip.drop;
246
#endif /* IP_STATS */
247
 
248
  }
249
  PERF_STOP("ip_input");
250
}
251
 
252
 
253
/* ip_output_if:
254
 *
255
 * Sends an IP packet on a network interface. This function constructs the IP header
256
 * and calculates the IP header checksum. If the source IP address is NULL,
257
 * the IP address of the outgoing network interface is filled in as source address.
258
 */
259
 
260
err_t
261
ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
262
       u8_t ttl,
263
       u8_t proto, struct netif *netif)
264
{
265
  struct ip_hdr *iphdr;
266
 
267
  PERF_START;
268
 
269
  printf("len %u tot_len %u\n", p->len, p->tot_len);
270
  if (pbuf_header(p, IP_HLEN)) {
271
    LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
272
#ifdef IP_STATS
273
    ++lwip_stats.ip.err;
274
#endif /* IP_STATS */
275
 
276
    return ERR_BUF;
277
  }
278
  printf("len %u tot_len %u\n", p->len, p->tot_len);
279
 
280
  iphdr = p->payload;
281
 
282
 
283
  if (dest != IP_HDRINCL) {
284
    printf("!IP_HDRLINCL\n");
285
    iphdr->hoplim = ttl;
286
    iphdr->nexthdr = proto;
287
    iphdr->len = htons(p->tot_len - IP_HLEN);
288
    ip_addr_set(&(iphdr->dest), dest);
289
 
290
    iphdr->v = 6;
291
 
292
    if (ip_addr_isany(src)) {
293
      ip_addr_set(&(iphdr->src), &(netif->ip_addr));
294
    } else {
295
      ip_addr_set(&(iphdr->src), src);
296
    }
297
 
298
  } else {
299
    dest = &(iphdr->dest);
300
  }
301
 
302
#ifdef IP_STATS
303
  ++lwip_stats.ip.xmit;
304
#endif /* IP_STATS */
305
 
306
  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %u)\n", netif->name[0], netif->name[1], p->tot_len));
307
#if IP_DEBUG
308
  ip_debug_print(p);
309
#endif /* IP_DEBUG */
310
 
311
  PERF_STOP("ip_output_if");
312
  return netif->output(netif, p, dest);
313
}
314
 
315
/* ip_output:
316
 *
317
 * Simple interface to ip_output_if. It finds the outgoing network interface and
318
 * calls upon ip_output_if to do the actual work.
319
 */
320
 
321
err_t
322
ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
323
    u8_t ttl, u8_t proto)
324
{
325
  struct netif *netif;
326
  if ((netif = ip_route(dest)) == NULL) {
327
    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%lx\n", dest->addr));
328
#ifdef IP_STATS
329
    ++lwip_stats.ip.rterr;
330
#endif /* IP_STATS */
331
    return ERR_RTE;
332
  }
333
 
334
  return ip_output_if (p, src, dest, ttl, proto, netif);
335
}
336
 
337
#if IP_DEBUG
338
void
339
ip_debug_print(struct pbuf *p)
340
{
341
  struct ip_hdr *iphdr = p->payload;
342
  char *payload;
343
 
344
  payload = (char *)iphdr + IP_HLEN;
345
 
346
  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
347
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
348
  LWIP_DEBUGF(IP_DEBUG, ("|%2d |  %x%x  |      %x%x           | (v, traffic class, flow label)\n",
349
        iphdr->v,
350
        iphdr->tclass1, iphdr->tclass2,
351
        iphdr->flow1, iphdr->flow2));
352
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
353
  LWIP_DEBUGF(IP_DEBUG, ("|    %5u      | %2u  |  %2u   | (len, nexthdr, hoplim)\n",
354
        ntohs(iphdr->len),
355
        iphdr->nexthdr,
356
        iphdr->hoplim));
357
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
358
  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",
359
        ntohl(iphdr->src.addr[0]) >> 16 & 0xffff,
360
        ntohl(iphdr->src.addr[0]) & 0xffff));
361
  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",
362
        ntohl(iphdr->src.addr[1]) >> 16 & 0xffff,
363
        ntohl(iphdr->src.addr[1]) & 0xffff));
364
  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",
365
        ntohl(iphdr->src.addr[2]) >> 16 & 0xffff,
366
        ntohl(iphdr->src.addr[2]) & 0xffff));
367
  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (src)\n",
368
        ntohl(iphdr->src.addr[3]) >> 16 & 0xffff,
369
        ntohl(iphdr->src.addr[3]) & 0xffff));
370
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
371
  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",
372
        ntohl(iphdr->dest.addr[0]) >> 16 & 0xffff,
373
        ntohl(iphdr->dest.addr[0]) & 0xffff));
374
  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",
375
        ntohl(iphdr->dest.addr[1]) >> 16 & 0xffff,
376
        ntohl(iphdr->dest.addr[1]) & 0xffff));
377
  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",
378
        ntohl(iphdr->dest.addr[2]) >> 16 & 0xffff,
379
        ntohl(iphdr->dest.addr[2]) & 0xffff));
380
  LWIP_DEBUGF(IP_DEBUG, ("|       %4lx      |       %4lx     | (dest)\n",
381
        ntohl(iphdr->dest.addr[3]) >> 16 & 0xffff,
382
        ntohl(iphdr->dest.addr[3]) & 0xffff));
383
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
384
}
385
#endif /* IP_DEBUG */
386
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.