ca04d9908fb6ec70151d194aab9b134b3550d901
Stefan Schuermans implemented IP + ICMP, fixe...

Stefan Schuermans authored 12 years ago

1) #include "config.h"
2) #include "checksum.h"
3) #include "ethernet.h"
Stefan Schuermans implement DHCP (not yet bug...

Stefan Schuermans authored 12 years ago

4) #include "dhcp.h"
Stefan Schuermans implemented IP + ICMP, fixe...

Stefan Schuermans authored 12 years ago

5) #include "ip.h"
6) #include "macros.h"
7) #include "nethelp.h"
8) #include "udp.h"
9) 
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

10) // some kind of "token bucket" for UDP echo
11) #define UDP_ECHO_TICKS 10 ///< allowed rate of UDP echo replies (in 200ms)
12) static unsigned int udp_echo_tick_cnt = 0; ///< tick counter
13) #define UDP_ECHO_REPLIES_MAX 3 ///< maximum value for udp_echo_replies
14) static unsigned int udp_echo_replies = 0; // # of allowed UDP echo replies
15) 
Stefan Schuermans implemented IP + ICMP, fixe...

Stefan Schuermans authored 12 years ago

16) /// tick procedure - call every 200ms
17) void udp_tick200(void)
18) {
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

19)   // count ticks
20)   udp_echo_tick_cnt++;
21)   // time to allow one reply more
22)   if (udp_echo_tick_cnt >= UDP_ECHO_TICKS) {
23)     udp_echo_tick_cnt = 0;
24) 
25)     // increase reply count if not at maximum
26)     if (udp_echo_replies < UDP_ECHO_REPLIES_MAX)
27)       udp_echo_replies++;
28)   }
29) }
30) 
31) /**
32)  * @brief process a received UDP echo packet
33)  * @param[in] ptr pointer to data of packet
34)  * @param[in] sz size of packet
35)  */
36) static void udp_echo_recv(void *ptr, unsigned int sz)
37) {
38)   struct udp_packet *udp_pack;
39) 
40)   udp_pack = ptr;
41) 
42)   // source port is UDP echo port
43)   if (udp_pack->udp_hdr.src_port == htons(7))
44)     // ignore this packet
45)     //  - UDP echo answer to another UDP echo port will result
46)     //    in endless echoing
47)     return;
48) 
49)   // only reply with allowed packet rate
50)   if (udp_echo_replies <= 0)
51)     return;
52)   udp_echo_replies--;
53) 
54)   // send an UDP echo
55)   //  - use same buffer to send reply
56)   //  - this saves us from allocating a new buffer
57)   //  - this saves us from copying the data
58)   udp_pack->udp_hdr.dest_port = udp_pack->udp_hdr.src_port; // to source port
59)   udp_pack->udp_hdr.src_port = htons(7); // UDP echo port
60)   ip_cpy( udp_pack->ip_hdr.dest, udp_pack->ip_hdr.src); // to source IP
61)   udp_send(udp_pack, sz);
Stefan Schuermans implemented IP + ICMP, fixe...

Stefan Schuermans authored 12 years ago

62) }
63) 
64) /**
65)  * @brief process a received UDP packet
66)  * @param[in] ptr pointer to data of packet
67)  * @param[in] sz size of packet
68)  */
69) void udp_recv(void *ptr, unsigned int sz)
70) {
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

71)   struct udp_packet *udp_pack;
72)   unsigned int len;
73) 
74)   // packet too short
75)   if (sz < sizeof(struct udp_packet))
76)     return;
77) 
78)   udp_pack = ptr;
79) 
80)   // ignore packets sent from or to port 0 (not allowed by RFC)
81)   if (udp_pack->udp_hdr.src_port == htons(0) ||
82)       udp_pack->udp_hdr.dest_port == htons(0))
83)     return;
84) 
85)   // check total length
86)   len = sizeof(struct ethernet_header) + sizeof(struct ip_header) +
87)         ntohs(udp_pack->udp_hdr.length); // length according to UDP header
88)   if (sz < len) // packet is truncated
89)     return;
90)   sz = len; // remove IP padding from packet (maybe sz > len)
91) 
92)   // test checksum
93)   if (checksum(&udp_pack->ip_hdr.src,
94)                 sz - sizeof(struct ethernet_header)
95)                    - sizeof(struct ip_header ) + 8,
96)                 0x0011,
97)                 ntohs(udp_pack->udp_hdr.length)))
98)     return;
99) 
100)   // branch according to destination port
101)   switch (ntohs(udp_pack->udp_hdr.dest_port)) {
102)     // UDP echo
103)     case 7:
104)       udp_echo_recv(ptr, sz);
105)       break;
Stefan Schuermans implement DHCP (not yet bug...

Stefan Schuermans authored 12 years ago

106)     // DHCP
107)     case 68:
108)       dhcp_recv(ptr, sz);
109)       break;
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

110)   }
Stefan Schuermans implemented IP + ICMP, fixe...

Stefan Schuermans authored 12 years ago

111) }
112) 
113) /**
114)  * @brief send a UDP packet
115)  * @param[in] ptr pointer to data of packet
116)  * @param[in] sz size of packet
117)  *
Stefan Schuermans handle padding to minimum e...

Stefan Schuermans authored 12 years ago

118)  * ptr must point to a udp_packet
Stefan Schuermans implement DHCP (not yet bug...

Stefan Schuermans authored 12 years ago

119)  * with ip_hdr.proto ip_hdr.dest, udp_hdr.src_port and udp_hdr.dest_port
Stefan Schuermans implemented IP + ICMP, fixe...

Stefan Schuermans authored 12 years ago

120)  * already initialized
121)  */
122) void udp_send(void *ptr, unsigned int sz)
123) {
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

124)   struct udp_packet *udp_pack;
125)   unsigned int chk;
126) 
127)   // packet too short
128)   if (sz < sizeof(struct udp_packet))
129)     return;
130) 
131)   udp_pack = ptr;
132) 
133)   // fill in header values
134)   udp_pack->udp_hdr.length = htons(sz - sizeof(struct ethernet_header)
135)                                       - sizeof(struct ip_header));
136)   udp_pack->udp_hdr.chk = 0x0000;
137)   /* put IP already here into IP header
138)      because it is needed for calculation of UDP checksum */
139)   ip_cpy(udp_pack->ip_hdr.src, config_ip.ip);
140) 
141)   // generate checksum
142)   chk = checksum(&udp_pack->ip_hdr.src,
143)                  sz - sizeof(struct ethernet_header )
144)                     - sizeof(struct ip_header ) + 8,
145)                  0x0011,
146)                  ntohs(udp_pack->udp_hdr.length));
147)   udp_pack->udp_hdr.chk = htons(chk);
148) 
149)   // send UDP packet
150)   udp_pack->ip_hdr.proto = 0x11; // UDP
151)   ip_send(udp_pack, sz);