Watt-32 tcp/ip  2.2 dev-rel.10
ip4_in.c
Go to the documentation of this file.
1 
11 #include <stdio.h>
12 #include <stdlib.h>
13 
14 #include "wattcp.h"
15 #include "misc.h"
16 #include "chksum.h"
17 #include "rs232.h"
18 #include "strings.h"
19 #include "pcconfig.h"
20 #include "pcigmp.h"
21 #include "pcdbug.h"
22 #include "pcsed.h"
23 #include "pctcp.h"
24 #include "pcstat.h"
25 #include "pcicmp.h"
26 #include "ip4_frag.h"
27 #include "ip4_in.h"
28 
29 /*
30  * _ip4_handler - do a simple check on IPv4 header.
31  * - check the fragment chain queue for a match.
32  * - Demultiplex packet to correct protocol handler.
33  */
34 int _ip4_handler (const in_Header *ip, BOOL broadcast)
35 {
36 #if defined(USE_FRAGMENTS)
37  const in_Header *in_ip = ip;
38 #endif
39  sock_type *s = NULL;
40  DWORD frag_ofs;
41  WORD frag_flg;
42  BOOL delivered = TRUE; /* assume yes */
43 
44  SIO_TRACE (("_ip4_handler"));
45 
46  if (block_ip || !_chk_ip4_header(ip))
47  return (0);
48 
49  frag_ofs = intel16 (ip->frag_ofs);
50  frag_flg = (WORD) (frag_ofs & ~IP_OFFMASK);
51  frag_ofs = (frag_ofs & IP_OFFMASK) << 3; /* 0 <= frag_ofs <= 65536-8 */
52 
53 #if defined(USE_FRAGMENTS)
54  if (!ip4_defragment(&ip,frag_ofs,frag_flg)) /* not defragged yet */
55  return (0);
56 #else
57  ARGSUSED (frag_flg);
58  if (frag_ofs)
59  return (0);
60 #endif
61 
67 #if defined(USE_BSD_API)
68  /*
69  * Match 'ip' against all SOCK_RAW sockets before doing normal
70  * protocol multiplexing below.
71  *
72  * Note: _bsd_socket_hook does nothing unless we have allocated at least
73  * one SOCK_RAW socket.
74  *
75  * Should we return if the hook consumed packet (returns non-NULL) ?
76  */
77  if (_bsd_socket_hook)
78  (*_bsd_socket_hook) (BSO_IP4_RAW, ip);
79 #endif
80 
81 
82  switch (ip->proto)
83  {
84  case TCP_PROTO:
85 #if !defined(USE_UDP_ONLY)
86  s = (sock_type*) _tcp_handler (ip, broadcast);
87 #endif
88  break;
89 
90  case UDP_PROTO:
91  s = (sock_type*) _udp_handler (ip, broadcast);
92  break;
93 
94  case ICMP_PROTO:
95  icmp_handler (ip, broadcast);
96  break;
97 
98  case IGMP_PROTO:
99 #if defined(USE_MULTICAST)
100  igmp_handler (ip, broadcast);
101 #endif
102  break;
103 
104  case IPCOMP_PROTO:
107  default:
108  DEBUG_RX (NULL, ip);
109  if (!broadcast)
110  {
111  if (_ip4_is_local_addr(intel(ip->destination)))
112  icmp_send_unreach (ip, ICMP_UNREACH_PROTOCOL);
113  STAT (ip4stats.ips_noproto++);
114  }
115  delivered = FALSE;
116  break;
117  }
118 
119 #ifdef NOT_USED
120  if (s) /* Check if peer allows IP-fragments */
121  {
122  if (intel16(ip->frag_ofs) & IP_DF)
123  s->tcp.locflags |= LF_NO_IPFRAGS;
124  else s->tcp.locflags &= ~LF_NO_IPFRAGMS;
125  }
126 #endif
127 
128 #if defined(USE_FRAGMENTS)
129  if (ip != in_ip)
130  ip4_free_fragment (ip); /* free this fragment chain */
131 #endif
132 
133  if (delivered)
134  STAT (ip4stats.ips_delivered++);
135  ARGSUSED (s);
136  return (1);
137 }
138 
139 /*
140  * Check for correct IP-version, header length and header checksum.
141  * If failed, discard the packet. ref. RFC1122: section 3.1.2.2
142  */
143 int _chk_ip4_header (const in_Header *ip)
144 {
145  unsigned hlen = in_GetHdrLen (ip);
146 
147  if (ip->ver != 4) /* We only speak IPv4 */
148  {
149  DEBUG_RX (NULL, ip);
150  STAT (ip4stats.ips_badvers++);
151  return (0);
152  }
153  if (hlen < sizeof(*ip))
154  {
155  DEBUG_RX (NULL, ip);
156  STAT (ip4stats.ips_tooshort++);
157  return (0);
158  }
159  if (CHECKSUM(ip,hlen) != 0xFFFF)
160  {
161  DEBUG_RX (NULL, ip);
162  STAT (ip4stats.ips_badsum++);
163  return (0);
164  }
165  return (1);
166 }
167 
168 /*
169  * Return TRUE if ip address is a local address or on the
170  * loopback network (127.x.x.x). `ip' is on host order.
171  * If netmask is 255.255.255.255, 'ip' *could* be remote.
172  */
173 int _ip4_is_local_addr (DWORD ip)
174 {
175  if (sin_mask == 0xFFFFFFFFUL)
176  return (0);
177  return _ip4_is_loopback_addr(ip) || _ip4_is_multihome_addr(ip);
178 }
179 
180 int _ip4_is_loopback_addr (DWORD ip)
181 {
182  return ((ip >> 24) == 127);
183 }
184 
185 /*
186  * Return TRUE if ip address is a legal address for
187  * a unique host. `ip' is on host order.
188  */
189 int _ip4_is_unique_addr (DWORD ip)
190 {
191  return (ip && (ip & ~sin_mask) == 0);
192 }
193 
194 /*
195  * Return TRUE if ip address is among our interface addresses
196  * [my_ip_addr.. (my_ip_addr+multihomes)], `ip' is on host order.
197  */
198 int _ip4_is_multihome_addr (DWORD ip)
199 {
200  if (!my_ip_addr || ip < my_ip_addr)
201  return (0);
202  if (ip - my_ip_addr <= multihomes)
203  return (1);
204  return (0);
205 }
206 
207 /*
208  * return TRUE if ip packet is a (directed) broadcast packet.
209  */
210 int _ip4_is_ip_brdcast (const in_Header *ip)
211 {
212  DWORD dst = intel (ip->destination);
213  return ((~dst & ~sin_mask) == 0); /* (directed) ip-broadcast */
214 }
215 
216 /*
217  * determines if the given IP addr is Class D (Multicast)
218  *
219  * int _ip4_is_multicast (DWORD ip)
220  * Where:
221  * `ip' is on host order.
222  * Returns:
223  * 1 if ip is Class D
224  * 0 if ip is not Class D
225  *
226  * Note: class-D is 224.0.0.0 - 239.255.255.255, but
227  * range 224.0.0.0 - 224.0.0.255 is reserved for mcast
228  * routing information.
229  */
230 int _ip4_is_multicast (DWORD ip)
231 {
232  return IN_MULTICAST(ip);
233 }
234 
_udp_Socket * _udp_handler(const in_Header *ip, BOOL broadcast)
Handler for incoming UDP packets.
Definition: pctcp.c:1031
int _ip4_handler(const in_Header *ip, BOOL broadcast)
Definition: ip4_in.c:34
Core definitions.
DWORD sin_mask
our net-mask, 255.255.255.0
Definition: pctcp.c:71
Definition: ip.h:67
void icmp_handler(const in_Header *ip, BOOL broadcast)
Handler for incoming ICMP packets.
Definition: pcicmp.c:376
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
int icmp_send_unreach(const in_Header *ip, int code)
Send an ICMP destination/protocol unreachable back to 'ip->source'.
Definition: pcicmp.c:194
DWORD my_ip_addr
our IP address
Definition: pctcp.c:70
_tcp_Socket * _tcp_handler(const in_Header *ip, BOOL broadcast)
The main TCP input handler.
Definition: pctcp.c:645