00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <const.h>
00012 #include <errno.h>
00013
00014 #include <kernel/console.h>
00015
00016 #include <net/ip.h>
00017 #include <net/network.h>
00018
00019 #include <net/udp.h>
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 uint16_t udp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr)
00030 {
00031 const uint16_t *buf=buff;
00032 uint16_t *ip_src=(void *)&src_addr, *ip_dst=(void *)&dest_addr;
00033 uint32_t sum;
00034 size_t length=len;
00035
00036
00037 sum = 0;
00038 while (len > 1)
00039 {
00040 sum += *buf++;
00041 if (sum & 0x80000000)
00042 sum = (sum & 0xFFFF) + (sum >> 16);
00043 len -= 2;
00044 }
00045
00046 if ( len & 1 )
00047
00048 sum += *((uint8_t *)buf);
00049
00050
00051 sum += *(ip_src++);
00052 sum += *ip_src;
00053
00054 sum += *(ip_dst++);
00055 sum += *ip_dst;
00056
00057 sum += htons(IPPROTO_UDP);
00058 sum += htons(length);
00059
00060
00061 while (sum >> 16)
00062 sum = (sum & 0xFFFF) + (sum >> 16);
00063
00064
00065 return ( (uint16_t)(~sum) );
00066 }
00067
00068
00069
00070
00071
00072
00073 void to_udp_layer(udp_t *packet, in_addr_t ip_src, in_addr_t ip_dst)
00074 {
00075 int i;
00076 bool chk;
00077 uint16_t len = ntohs(packet->udp_len) - sizeof(udp_t);
00078
00079
00080
00081
00082 if ( packet->udp_chk != 0 )
00083 {
00084
00085 if ( packet->udp_chk == 0xFFFF )
00086 packet->udp_chk = 0x0000;
00087
00088
00089 chk = udp_checksum(
00090 packet,
00091 ntohs(packet->udp_len),
00092 ip_src,
00093 ip_dst
00094 );
00095 if ( chk )
00096 {
00097 kprintf("\n\rUDP checksum error! %04X", chk);
00098 return;
00099 }
00100 }
00101
00102
00103 kprintf( "\n\rUDP packet received (%u bytes of data)"
00104 "\n\rsender = %u.%u.%u.%u:%u"
00105 "\n\rreceiver= %u.%u.%u.%u:%u",
00106 len,
00107
00108 IP_A(ntohl(ip_src)), IP_B(ntohl(ip_src)),
00109 IP_C(ntohl(ip_src)), IP_D(ntohl(ip_src)),
00110 ntohs(packet->udp_src),
00111
00112 IP_A(ntohl(ip_dst)), IP_B(ntohl(ip_dst)),
00113 IP_C(ntohl(ip_dst)), IP_D(ntohl(ip_dst)),
00114 ntohs(packet->udp_dst)
00115 );
00116
00117 kprintf("\n\rData:\n\r");
00118 for(i=0; i<len; i++)
00119 kputchar( (((uint8_t *)packet)+sizeof(udp_t))[i] );
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 int recv_udp_packet(udp_t *buf, size_t len, int flags)
00133 {
00134 return( -ENOPROTOOPT );
00135 }