implemented IP + ICMP, fixe...
Stefan Schuermans authored 12 years ago
|
1) #include "arp.h"
2) #include "checksum.h"
3) #include "config.h"
4) #include "ethernet.h"
5) #include "icmp.h"
6) #include "ip.h"
7) #include "macros.h"
8) #include "memcpy.h"
9) #include "nethelp.h"
10) #include "udp.h"
11)
12) // timing parameters
13) #define IP_BUFFER_TICKS_MAX 50 // maximum age of buffered IP packet (in 200ms)
14)
15) /**
16) * buffers for IP packets to transmit
17) * - used if MAC is unknown when packet shall be transmitted
18) * - packet is sent when MAC becomes known
19) * - some buffers with different length (packets have different lengths)
20) */
21) //@{
22) unsigned int ip_buffer0[20];
23) unsigned int ip_buffer1[20];
24) unsigned int ip_buffer2[40];
25) unsigned int ip_buffer3[80];
26) //@}
27) /// table with buffers
28) struct ip_buffer_table
29) {
30) void *ptr; ///< pointer to buffer for packet
31) unsigned int buf_sz; ///< size of buffer
32) unsigned int pkg_sz; ///< size of packet in buffer, 0 for packet
33) unsigned int ticks; //< age of entry (in 200ms)
34) } ip_buffer_tab[] =
35) { // put smaller buffers in front of larger buffers
36) // - then short packets will use smaller buffers more often
37) { ip_buffer0, sizeof(ip_buffer0), 0, 0 },
38) { ip_buffer1, sizeof(ip_buffer1), 0, 0 },
39) { ip_buffer2, sizeof(ip_buffer2), 0, 0 },
40) { ip_buffer3, sizeof(ip_buffer3), 0, 0 },
41) };
42)
43) /// initialize
44) void ip_init(void)
45) {
46) unsigned int i;
47) for (i = 0; i < count(ip_buffer_tab ); i++)
48) ip_buffer_tab[i].pkg_sz = 0;
49) }
50)
51) /// tick procedure - call every 200ms
52) void ip_tick200(void)
53) {
54) unsigned int i;
55)
56) // increase age of buffered IP packets and remove timed out ones
57) for (i = 0; i < count( ip_buffer_tab ); i++) {
58) if (ip_buffer_tab[i].pkg_sz > 0 ) { // buffer in use
59) ip_buffer_tab[i].ticks++; // increase age
60) if (ip_buffer_tab[i].ticks > IP_BUFFER_TICKS_MAX) // too old
61) ip_buffer_tab[i].pkg_sz = 0; // discard packet
62) }
63) }
64) }
65)
66) /**
67) * @brief process a received IP packet
68) * @param[in] ptr pointer to data of packet
69) * @param[in] sz size of packet
70) */
71) void ip_recv(void *ptr, unsigned int sz)
72) {
73) struct ip_packet *ip_pack;
74) unsigned int len;
75)
76) // packet too short
77) if (sz < sizeof(struct ip_packet))
78) return;
79)
80) ip_pack = ptr;
81)
82) // not IPv4 -> drop
83) if (ip_pack->ip_hdr.ver__hdr_len != 0x45) // IPv4 with no options present
84) return;
85)
86) // not to own IP / broadcast -> drop
87) while (1) {
88) // own IP -> accept
89) if (ip_eq(ip_pack->ip_hdr.dest, config_ip.ip) )
90) break;
91) // local network's broadcast address -> accept
92) if ((ip_pack->ip_hdr.dest[0] & config_ip.mask[0]) ==
93) (config_ip.ip[0] & config_ip.mask[0]) &&
94) (ip_pack->ip_hdr.dest[1] & config_ip.mask[1]) ==
95) (config_ip.ip[1] & config_ip.mask[1]) &&
96) (ip_pack->ip_hdr.dest[2] & config_ip.mask[2]) ==
97) (config_ip.ip[2] & config_ip.mask[2]) &&
98) (ip_pack->ip_hdr.dest[3] & config_ip.mask[3]) ==
99) (config_ip.ip[3] & config_ip.mask[3]) &&
100) (ip_pack->ip_hdr.dest[0] & ~config_ip.mask[0]) ==
101) ~config_ip.mask[0] &&
102) (ip_pack->ip_hdr.dest[1] & ~config_ip.mask[1]) ==
103) ~config_ip.mask[1] &&
104) (ip_pack->ip_hdr.dest[2] & ~config_ip.mask[2]) ==
105) ~config_ip.mask[2] &&
106) (ip_pack->ip_hdr.dest[3] & ~config_ip.mask[3]) ==
107) ~config_ip.mask[3] )
108) break;
109) // link local boradcast address -> accept
110) if (ip_pack->ip_hdr.dest[0] == 0xFF &&
111) ip_pack->ip_hdr.dest[1] == 0xFF &&
112) ip_pack->ip_hdr.dest[2] == 0xFF &&
113) ip_pack->ip_hdr.dest[3] == 0xFF )
114) break;
115) // drop
116) return;
117) }
118)
119) // ignore packets sent from invalid source adresses
120) // - this might be some attack or some router fault
121) if (ip_pack->ip_hdr.src[0] >= 0xE0 || // broadcast, reserved or multicast
122) ip_pack->ip_hdr.src[0] == 0x7F || // loopback network
123) ip_eq(ip_pack->ip_hdr.src, "\x00\x00\x00\x00" )) // IP 0.0.0.0
124) return;
125) // ignore packets sent from local network or broadcast address
126) if ((ip_pack->ip_hdr.src[0] & config_ip.mask[0]) ==
127) (config_ip.ip[0] & config_ip.mask[0]) && // source IP is in own subnet
128) (ip_pack->ip_hdr.src[1] & config_ip.mask[1]) ==
129) (config_ip.ip[1] & config_ip.mask[1]) &&
130) (ip_pack->ip_hdr.src[2] & config_ip.mask[2]) ==
131) (config_ip.ip[2] & config_ip.mask[2]) &&
132) (ip_pack->ip_hdr.src[3] & config_ip.mask[3]) ==
133) (config_ip.ip[3] & config_ip.mask[3]))
134) {
135) // local network address
136) if ((ip_pack->ip_hdr.src[0] & ~config_ip.mask[0]) == 0x00 &&
137) (ip_pack->ip_hdr.src[1] & ~config_ip.mask[1]) == 0x00 &&
138) (ip_pack->ip_hdr.src[2] & ~config_ip.mask[2]) == 0x00 &&
139) (ip_pack->ip_hdr.src[3] & ~config_ip.mask[3]) == 0x00 )
140) return;
141) // local broadcast address
142) if ((ip_pack->ip_hdr.src[0] & ~config_ip.mask[0]) == 0xFF &&
143) (ip_pack->ip_hdr.src[1] & ~config_ip.mask[1]) == 0xFF &&
144) (ip_pack->ip_hdr.src[2] & ~config_ip.mask[2]) == 0xFF &&
145) (ip_pack->ip_hdr.src[3] & ~config_ip.mask[3]) == 0xFF )
146) return;
147) }
148) // ignore packets sent from own IP address
149) if (ip_eq(ip_pack->ip_hdr.src, config_ip.ip))
150) return;
151)
152) // ignore fragmented packets
153) // BUG: fragmentation must be supported according to RFC781
154) // but there is not enough RAM for assembling packets with up to 64kB
155) // fragment offset 0, more_frags=0, dont_frag=x, reserved_flag=0
156) if ((ntohs(ip_pack->ip_hdr.frag_ofs) & 0xBFFF) != 0x0000)
157) return;
158)
159) // check total length
160) len = sizeof(struct ethernet_header ) + ntohs(ip_pack->ip_hdr.total_len);
161) if (sz < len) // packet is truncated
162) return;
163) sz = len; // remove ethernet padding from packet (maybe sz > len)
164)
165) // test header checksum
166) if (checksum(&ip_pack->ip_hdr, sizeof(struct ip_header), 0x0000, 0x0000))
167) return;
168)
169) // branch according to protocol
170) switch(ip_pack->ip_hdr.proto) {
171) // ICMP
172) case 0x01:
173) icmp_recv(ptr, sz);
174) break;
175) // UDP
176) case 0x11:
177) udp_recv(ptr, sz);
178) break;
179) }
180) }
181)
182) /**
183) * @brief send an IP packet
184) * @param[in] ptr pointer to data of packet
185) * @param[in] sz size of packet
186) *
|