7ec9ac6202358c2e21e066a5ef03ce5f8c6a4d98
Stefan Schuermans implemented IP + ICMP, fixe...

Stefan Schuermans authored 12 years ago

1) #include "config.h"
2) #include "checksum.h"
3) #include "ethernet.h"
4) #include "ip.h"
5) #include "macros.h"
6) #include "nethelp.h"
7) #include "udp.h"
8) 
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

106) }
107) 
108) /**
109)  * @brief send a UDP packet
110)  * @param[in] ptr pointer to data of packet
111)  * @param[in] sz size of packet
112)  *
Stefan Schuermans handle padding to minimum e...

Stefan Schuermans authored 12 years ago

113)  * ptr must point to a udp_packet
Stefan Schuermans implemented IP + ICMP, fixe...

Stefan Schuermans authored 12 years ago

114)  * with ip_hdr.proto and udp_hdr.src_port, udp_hdr.dest_port, ip_hdr.dest
115)  * already initialized
116)  */
117) void udp_send(void *ptr, unsigned int sz)
118) {
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

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