initial commit after making...
Stefan Schuermans authored 12 years ago
|
14) #include "nethelp.h"
15) #include "ser62500.h"
16) #include "udp.h"
17)
18) // some kind of "token bucket" for UDP echo
19) #define UdpEchoTicks 10 // allowed rate of UDP echo replies (in 200ms steps)
20) unsigned char UdpEchoTickCnt = 0; // tick counter
21) #define UdpEchoReliesMax 3 // maximum value for UdpEchoReplies
22) unsigned char UdpEchoReplies = 0; // number of UDP echo replies that
23) // may be sent at the moment
24)
25) // tick procedure - call every 200ms
26) void UdpTick200(void) // (extern)
27) {
28) // count ticks
29) UdpEchoTickCnt++;
30) // time to allow one reply more
31) if (UdpEchoTickCnt >= UdpEchoTicks) {
32) UdpEchoTickCnt = 0;
33)
34) // increase reply count if not at maximum
35) if (UdpEchoReplies < UdpEchoReliesMax)
36) UdpEchoReplies++;
37) }
38) }
39)
40) // process a received UDP echo packet
41) static void UdpEchoRecv(unsigned char *pData, unsigned short Length)
42) {
43) struct UdpPacket *pUdpPack;
44)
45) // convert pointer to UDP packet
46) // (this saves us from always casting pData)
47) pUdpPack = (struct UdpPacket *)pData;
48)
49) // source port is UDP echo port
50) if (pUdpPack->UdpHdr.SrcPort == htons(7))
51) // ignore this packet
52) // - UDP echo answer to another UDP echo port will result in endless
53) // echoing
54) return;
55)
56) // only reply with allowed packet rate
57) if (UdpEchoReplies == 0) {
58) debug_udp_printf("echo len=%u (dropped)", Length);
59) return;
60) }
61) UdpEchoReplies--;
62)
63) debug_udp_printf("echo len=%u", Length);
64)
65) // send an UDP echo
66) // - use same buffer to send reply
67) // - this saves us from allocating a new buffer
68) // - this saves us from copying the data
69) pUdpPack->UdpHdr.DestPort = pUdpPack->UdpHdr.SrcPort; // back to
70) // originationg port
71) pUdpPack->UdpHdr.SrcPort = htons(7); // UDP echo port
72) ip_cpy(pUdpPack->IpHdr.Dest, pUdpPack->IpHdr.Src); // back to
73) // originating IP
74) UdpSend(pData, Length);
75) }
76)
77) // process a received UDP packet
78) void UdpRecv(unsigned char *pData, unsigned short Length) // (extern)
79) {
80) struct UdpPacket *pUdpPack;
81) unsigned int len;
82)
83) // packet too short
84) if (Length < sizeof(struct UdpPacket))
85) return;
86)
87) // convert pointer to UDP packet
88) // (this saves us from always casting pData)
89) pUdpPack = (struct UdpPacket *)pData;
90)
91) // ignore packets sent from or to port 0
92) // - this might be some attack
93) if (pUdpPack->UdpHdr.SrcPort == htons(0) ||
94) pUdpPack->UdpHdr.DestPort == htons(0))
95) return;
96)
97) // check total length
98) len = sizeof(struct EthernetHeader) + sizeof(struct IpHeader) + ntohs(pUdpPack->UdpHdr.Length); // length
99) // according
100) // to
101) // UDP
102) // header
103) if (Length < len) // packet is truncated
104) return;
105) Length = len; // remove IP padding from packet (maybe Length > len)
106)
107) // test checksum
108) if (Checksum((unsigned char *)&pUdpPack->IpHdr.Src,
109) Length - sizeof(struct EthernetHeader) -
110) sizeof(struct IpHeader) + 8, 0x0011,
111) ntohs(pUdpPack->UdpHdr.Length)) != 0)
112) return;
113)
114) debug_udp_printf("recv src=%u dest=%u len=%u",
115) ntohs(pUdpPack->UdpHdr.SrcPort),
116) ntohs(pUdpPack->UdpHdr.DestPort), Length);
117)
118) // branch according to destination port
119) switch (ntohs(pUdpPack->UdpHdr.DestPort)) {
120) // UDP echo
121) case 7:
122) UdpEchoRecv(pData, Length);
123) break;
124) // DHCP
125) case 68:
126) DhcpRecv(pData, Length);
127) break;
|