Watt-32 tcp/ip  2.2 dev-rel.10
ip6_in.c
Go to the documentation of this file.
1 
5 /*
6  * Copyright (c) 1997-2002 Gisle Vanem <gvanem@yahoo.no>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  * must display the following acknowledgement:
18  * This product includes software developed by Gisle Vanem
19  * Bergen, Norway.
20  *
21  * THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * Version
33  *
34  * 0.5 : Jul 29, 2002 : G. Vanem - created
35  *
36  */
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <arpa/inet.h>
41 
42 #include "wattcp.h"
43 #include "misc.h"
44 #include "chksum.h"
45 #include "rs232.h"
46 #include "strings.h"
47 #include "language.h"
48 #include "sock_ini.h"
49 #include "split.h"
50 #include "pctcp.h"
51 #include "pcsed.h"
52 #include "pcstat.h"
53 #include "pcdbug.h"
54 #include "pcpkt.h"
55 #include "pcconfig.h"
56 #include "pcicmp6.h"
57 #include "bsddbug.h"
58 #include "netaddr.h"
59 #include "get_xby.h"
60 #include "ip6_out.h"
61 #include "ip6_in.h"
62 
63 /* \if USE_IPV6 */
64 #if defined(USE_IPV6)
65 
66 /*
67  * _ip6_handler - do a simple check on IPv6 header
68  * - Demultiplex packet to correct protocol handler
69  */
70 int _ip6_handler (const in6_Header *ip, BOOL broadcast)
71 {
72  const struct pkt_split *ps;
73 
74  SIO_TRACE (("_ip6_handler"));
75 
76  if (block_ip)
77  return (0);
78 
79  if (ip->ver != 6)
80  {
81  DEBUG_RX (NULL, ip);
82  STAT (ip6stats.ip6s_badvers++);
83  return (0);
84  }
85 
86  /* Match 'ip' against all SOCK_RAW sockets before doing normal
87  * protocol multiplexing below.
88  */
89  if (_bsd_socket_hook)
90  (*_bsd_socket_hook) (BSO_IP6_RAW, ip);
91 
92  for (ps = pkt_get_split_in(); ps->data; ps++)
93  switch (ps->type)
94  {
95  case TYPE_TOKEN_HEAD:
96  case TYPE_FDDI_HEAD:
97  case TYPE_ETHER_HEAD:
98  case TYPE_IP6:
99  break;
100 
101  case TYPE_TCP_HEAD:
102  _tcp_handler ((const in_Header*)ip, broadcast);
103  break;
104 
105  case TYPE_UDP_HEAD:
106  _udp_handler ((const in_Header*)ip, broadcast);
107  break;
108 
109  case TYPE_IP6_ICMP:
110  icmp6_handler (ip);
111  break;
112 
113  case TYPE_IP6_NONE:
114  break;
115 
116  case TYPE_IP6_UNSUPP:
117 #if defined(USE_DEBUG)
118  dbug_printf ("Received unsupported IPv6 message, next-hdr %d,"
119  " broadcast %d\n", ip->next_hdr, broadcast);
120 #endif
121  break;
122 
123  default:
124  DEBUG_RX (NULL, ip);
125  if ((ps->type >= TYPE_IP6_HOP && ps->type <= TYPE_IP6_DEST) &&
126  !broadcast)
127  {
128  if (IN6_IS_ADDR_LINKLOCAL(&ip->destination))
129  icmp6_unreach (ip, 2); /* protocol unreachable */
130  STAT (ip6stats.ip6s_cantforward++);
131  }
132  break;
133  }
134 
135 #if 0
136  if (ip->next_hdr != IP6_NEXT_ICMP) /* !! bug hunt */
137  dbug_printf ("IP6 packet, next-hdr %d, brdcast %d\n",
138  ip->next_hdr, broadcast);
139 #endif
140 
141  STAT (ip6stats.ip6s_delivered++);
142  return (1);
143 }
144 
145 /*
146  * Return TRUE if IPv6 address is a local address or on the
147  * loopback network (::1).
148  */
149 int _ip6_is_local_addr (const void *ip)
150 {
151  if (!memcmp(&in6addr_my_ip,ip,sizeof(in6addr_my_ip)) ||
152  !memcmp(&in6addr_loopback,ip,sizeof(in6addr_loopback)))
153  return (1);
154  return (0);
155 }
156 
157 #ifdef NOT_USED /* use IN6_xx macros in <netinet/in.h> instead */
158 /*
159  * Return true if address has a IPv4 prefix (0:0:0:0:0:FFFF)
160  */
161 static WORD v4_prefix[6] = { 0,0,0,0,0,0xFFFF };
162 
163 int _ip6_is_addr_v4mapped (const void *ip)
164 {
165  if (!memcmp(ip,&v4_prefix,sizeof(v4_prefix)))
166  return (1);
167  return (0);
168 }
169 
170 int _ip6_is_addr_loopback (const void *ip)
171 {
172  if (!memcmp(ip,&in6addr_loopback,sizeof(in6addr_loopback)))
173  return (1);
174  return (0);
175 }
176 #endif /* NOT_USED */
177 
178 
179 static void (W32_CALL *prev_hook) (const char*, const char*) = NULL;
180 
181 static void set_my_ip6 (const char *value)
182 {
183  if (!stricmp(value,"dhcp") || !stricmp(value,"dhcp6"))
184  _dhcp6_on = 1;
185  else if (!inet_pton(AF_INET6, value, (void*)&in6addr_my_ip))
186  printf (_LANG("\"IP6.MY_IP\": Invalid IPv6 address \"%s\"\n"), value);
187 }
188 
189 static void W32_CALL ip6_config (const char *name, const char *value)
190 {
191  static const struct config_table ip6_cfg[] = {
192  { "MY_IP", ARG_FUNC, (void*)set_my_ip6 },
193  { "6TO4_GATEWAY", ARG_ATOIP, (void*)&icmp6_6to4_gateway },
194  { "DEF_TTL", ARG_ATOI, (void*)&_default6_ttl },
195  { NULL, 0, NULL }
196  };
197  if (!parse_config_table(&ip6_cfg[0], "IP6.", name, value) && prev_hook)
198  (*prev_hook) (name, value);
199 }
200 
201 int _ip6_init (void)
202 {
203  prev_hook = usr_init;
204  usr_init = ip6_config;
205  return (1);
206 }
207 
208 /*
209  * Sets default (preferred link-local) IPv6 address to
210  * FE80::201:80FF:FE <last 3 bytes of MAC-address>
211  */
212 static void set_default_ip (void)
213 {
214  BYTE *a = (BYTE*) &in6addr_my_ip.s6_addr[0];
215 
216  memset (a, 0, sizeof(in6addr_my_ip));
217  a[0] = 0xFE;
218  a[1] = 0x80;
219  a[8] = 0x20;
220  a[9] = 0x01;
221  a[10] = 0x80;
222  a[11] = 0xFF;
223  a[12] = 0xFE;
224  a[13] = _eth_real_addr[3];
225  a[14] = _eth_real_addr[4];
226  a[15] = _eth_real_addr[5];
227 }
228 
229 /*
230  * Called from socket.c only (I.e. IPv6 requires BSD-sockets. Core
231  * API cannot be used for IPv6).
232  */
233 int _ip6_pkt_init (void)
234 {
235  if (!memcmp(&in6addr_my_ip,&in6addr_any,sizeof(in6addr_my_ip)))
236  set_default_ip();
237 
238  if (_pktserial) /* IPv6 cannot work on any known serial drivers */
239  return (0);
240 
241  /* Ignore result, not much we can do if it fails anyway.
242  */
243  if (_pkt_rxmode < RXMODE_MULTICAST2) /* if not already set */
245  return (1); /* promiscous mode is okay */
246 }
247 
248 /*
249  * Called from sock_ini.c after config read
250  */
251 void _ip6_post_init (void)
252 {
253  if (icmp6_6to4_gateway)
254  icmp6_add_gateway4();
255 }
256 #endif /* USE_IPV6 */
257 /* \endif */
int W32_CALL parse_config_table(const struct config_table *tab, const char *section, const char *name, const char *value)
Parse the config-table and if a match is found for ('section'+'.
Definition: pcconfig.c:379
convert to int
Definition: tcp.h:424
call convertion function
Definition: tcp.h:434
_udp_Socket * _udp_handler(const in_Header *ip, BOOL broadcast)
Handler for incoming UDP packets.
Definition: pctcp.c:1031
int pkt_set_rcv_mode(int mode)
Sets the receive mode of the interface.
Definition: pcpkt.c:1955
mac_address _eth_real_addr
Our real MAC address.
Definition: pcsed.c:53
BOOL _dhcp6_on
Try booting using DHCP6 ?
Definition: sock_ini.c:131
Core definitions.
Definition: ip.h:67
int W32_CALL inet_pton(int af, const char *src, void *dst)
Convert from presentation format (which usually means ASCII printable) to network format (which is us...
Definition: presaddr.c:66
BOOL _pktserial
using serial driver, SLIP/PPP
Definition: pcpkt.c:54
void *MS_CDECL * _bsd_socket_hook(enum BSD_SOCKET_OPS op,...)
This hook is to prevent the BSD-socket API being linked in by default.
BOOL block_ip
when application handles IP itself
Definition: pctcp.c:68
BROADCAST + all multicast.
Definition: pcpkt.h:113
int _pkt_rxmode
active receive mode
Definition: pcpkt.c:56
_tcp_Socket * _tcp_handler(const in_Header *ip, BOOL broadcast)
The main TCP input handler.
Definition: pctcp.c:645
convert to ip-address (host order)
Definition: tcp.h:427