c2b040193a777c09bdc595c95492b57a2521db87
Stefan Schuermans added file headers

Stefan Schuermans authored 12 years ago

1) /* MIPS I system
2)  * Copyright 2011-2012 Stefan Schuermans <stefan@schuermans.info>
3)  * Copyleft GNU public license V2 or later
4)  *          http://www.gnu.org/copyleft/gpl.html
5)  */
6) 
Stefan Schuermans implemented IP + ICMP, fixe...

Stefan Schuermans authored 12 years ago

7) #include "config.h"
8) #include "checksum.h"
9) #include "ethernet.h"
Stefan Schuermans implement DHCP (not yet bug...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

11) #include "ip.h"
12) #include "macros.h"
13) #include "nethelp.h"
14) #include "udp.h"
15) 
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

22) /// tick procedure - call every 200ms
23) void udp_tick200(void)
24) {
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

68) }
69) 
70) /**
71)  * @brief process a received UDP packet
72)  * @param[in] ptr pointer to data of packet
73)  * @param[in] sz size of packet
74)  */
75) void udp_recv(void *ptr, unsigned int sz)
76) {
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

112)     // DHCP
113)     case 68:
114)       dhcp_recv(ptr, sz);
115)       break;
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

117) }
118) 
119) /**
120)  * @brief send a UDP packet
121)  * @param[in] ptr pointer to data of packet
122)  * @param[in] sz size of packet
123)  *
Stefan Schuermans handle padding to minimum e...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

125)  * 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

126)  * already initialized
127)  */
128) void udp_send(void *ptr, unsigned int sz)
129) {
Stefan Schuermans implemented UDP functions

Stefan Schuermans authored 12 years ago

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