📄 udp.c
字号:
#include "udp.h"
#include <string.h>
u8_t uip_buf[UIP_BUFSIZE+2];
volatile u8_t *uip_appdata;
u16_t uip_len, uip_slen;
volatile u8_t uip_flags;
struct uip_udp_conn *uip_udp_conn;
struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
UIP_ETHADDR1,
UIP_ETHADDR2,
UIP_ETHADDR3,
UIP_ETHADDR4,
UIP_ETHADDR5}};
static u16_t lastport=1024;
static u16_t ipid;
static u8_t i, c;
static u16_t tmp16;
static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
static u16_t ipaddr[2];
static u8_t arptime;
static u8_t tmpage;
#define BUF ((struct arp_hdr *)&uip_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define ARP_REQUEST 1
#define ARP_REPLY 2
#define ICMP_ECHO_REPLY 0
#define ICMP_ECHO 8
#define ARP_HWTYPE_ETH 1
const u16_t uip_hostaddr[2] =
{HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
const u16_t uip_arp_draddr[2] =
{HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
const u16_t uip_arp_netmask[2] =
{HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
void udp_init(void)
{
for(c = 0; c < UIP_UDP_CONNS; ++c) {
uip_udp_conns[c].lport = 0;
}
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
memset(arp_table[i].ipaddr, 0, 4);
}
}
void uip_arp_timer(void)
{
struct arp_entry *tabptr;
++arptime;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
arptime - tabptr->time >= UIP_ARP_MAXAGE) {
memset(tabptr->ipaddr, 0, 4);
}
}
}
static void uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
{
register struct arp_entry *tabptr;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(tabptr->ipaddr[0] != 0 &&tabptr->ipaddr[1] != 0) {
if(ipaddr[0] == tabptr->ipaddr[0] &&ipaddr[1] == tabptr->ipaddr[1]) {
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
return;
}
}
}
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(tabptr->ipaddr[0] == 0 &&tabptr->ipaddr[1] == 0) {
break;
}
}
if(i == UIP_ARPTAB_SIZE) {
tmpage = 0;
c = 0;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(arptime - tabptr->time > tmpage) {
tmpage = arptime - tabptr->time;
c = i;
}
}
tabptr=&arp_table[c];
}
memcpy(tabptr->ipaddr, ipaddr, 4);
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
}
void uip_arp_ipin(void)
{
uip_len -= sizeof(struct uip_eth_hdr);
if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) !=
(uip_hostaddr[0] & uip_arp_netmask[0])) {
return;
}
if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
(uip_hostaddr[1] & uip_arp_netmask[1])) {
return;
}
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
return;
}
typedef struct arp_hdr aht;
void uip_arp_arpin(void)
{
if(uip_len < 60){
uip_len = 0;
return;
}
if((BUF->sipaddr[0] == uip_hostaddr[0]) &&
(BUF->sipaddr[1] == uip_hostaddr[1])){
uip_len = 0;
return;
}
if((BUF->dipaddr[0] != uip_hostaddr[0]) ||
(BUF->dipaddr[1] != uip_hostaddr[1])){
uip_len = 0;
return;
}
uip_len = 0;
switch(BUF->opcode) {
case HTONS(ARP_REQUEST):
BUF->opcode = HTONS(2);
memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
BUF->dipaddr[0] = BUF->sipaddr[0];
BUF->dipaddr[1] = BUF->sipaddr[1];
BUF->sipaddr[0] = uip_hostaddr[0];
BUF->sipaddr[1] = uip_hostaddr[1];
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uip_len = 60;
break;
case HTONS(ARP_REPLY):
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
break;
}
}
void uip_arp_out(void)
{
struct arp_entry *tabptr;
ipaddr[0] = IPBUF->destipaddr[0];
ipaddr[1] = IPBUF->destipaddr[1];
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(ipaddr[0] == tabptr->ipaddr[0] &&
ipaddr[1] == tabptr->ipaddr[1])
break;
}
if(i == UIP_ARPTAB_SIZE) {
memset(BUF->ethhdr.dest.addr, 0xff, 6);
memset(BUF->dhwaddr.addr, 0x00, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
BUF->dipaddr[0] = ipaddr[0];
BUF->dipaddr[1] = ipaddr[1];
BUF->sipaddr[0] = uip_hostaddr[0];
BUF->sipaddr[1] = uip_hostaddr[1];
BUF->opcode = HTONS(ARP_REQUEST);
BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
BUF->protocol = HTONS(UIP_ETHTYPE_IP);
BUF->hwlen = 6;
BUF->protolen = 4;
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uip_appdata = &uip_buf[UIP_LLH_LEN];
uip_len = 60;
return;
}
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
uip_len += sizeof(struct uip_eth_hdr);
}
struct uip_udp_conn * uip_udp_new(u16_t *ripaddr, u16_t rport)
{
register struct uip_udp_conn *conn;
u8_t c;
again:
++lastport;
if(lastport >= 32000) {
lastport = 1024;
}
for(c = 0; c < UIP_UDP_CONNS; ++c) {
if(uip_udp_conns[c].lport == lastport) {
goto again;
}
}
conn = 0;
for(c = 0; c < UIP_UDP_CONNS; ++c) {
if(uip_udp_conns[c].lport == 0) {
conn = &uip_udp_conns[c];
break;
}
}
if(conn == 0) {
return 0;
}
conn->lport = HTONS(lastport);
conn->rport = HTONS(rport);
conn->ripaddr[0] = ripaddr[0];
conn->ripaddr[1] = ripaddr[1];
return conn;
}
void udp_process(void)
{
u16_t j;
if(UDPBUF->vhl != 0x45){
goto drop;
}
if((UDPBUF->destipaddr[0] != uip_hostaddr[0]) ||
(UDPBUF->destipaddr[1] != uip_hostaddr[1])){
goto drop;
}
if((UDPBUF->srcipaddr[0] == uip_hostaddr[0]) &&
(UDPBUF->srcipaddr[1] == uip_hostaddr[1])){
goto drop;
}
if (uip_ipchksum() != 0xffff){
goto drop;
}
switch(UDPBUF->proto){
case UIP_PROTO_ICMP:
goto icmp_input;
case UIP_PROTO_UDP:
goto udp_input;
default:
goto drop;
}
icmp_input:
if (ICMPBUF->type != ICMP_ECHO){
goto drop;
}
j = (((ICMPBUF->len[0])<<8)+(ICMPBUF->len[1]) - 20);
if (uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN+20],j) != 0xffff){
goto drop;
}
ICMPBUF->type = ICMP_ECHO_REPLY;
if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
} else {
ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
}
tmp16 = IPBUF->destipaddr[0];
UDPBUF->destipaddr[0] = UDPBUF->srcipaddr[0];
UDPBUF->srcipaddr[0] = tmp16;
tmp16 = UDPBUF->destipaddr[1];
UDPBUF->destipaddr[1] = UDPBUF->srcipaddr[1];
UDPBUF->srcipaddr[1] = tmp16;
return;
udp_input:
for(uip_udp_conn = &uip_udp_conns[0]; uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; ++uip_udp_conn) {
if(uip_udp_conn->lport != 0 &&UDPBUF->destport == uip_udp_conn->lport &&
(uip_udp_conn->rport == 0 ||UDPBUF->srcport == uip_udp_conn->rport) &&
UDPBUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
UDPBUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
uip_len = uip_slen = 0;
uip_flags = UIP_NEWDATA;
UIP_UDP_APPCALL();
break;
}
else
goto drop;
}
if(uip_slen == 0)
{
goto drop;
}
uip_len = uip_slen + 8 + 20;
UDPBUF->vhl = 0x45;
UDPBUF->tos = 0;
UDPBUF->len[0] = (uip_len >> 8);
UDPBUF->len[1] = (uip_len & 0xff);
UDPBUF->ipoffset[0] = UDPBUF->ipoffset[1] = 0;
UDPBUF->ttl = UIP_TTL;
++ipid;
UDPBUF->ipid[0] = ipid >> 8;
UDPBUF->ipid[1] = ipid & 0xff;
UDPBUF->proto = UIP_PROTO_UDP;
UDPBUF->ipchksum = ~(uip_ipchksum());
UDPBUF->srcipaddr[0] = uip_hostaddr[0];
UDPBUF->srcipaddr[1] = uip_hostaddr[1];
UDPBUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
UDPBUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
UDPBUF->srcport = uip_udp_conn->lport;
UDPBUF->destport = uip_udp_conn->rport;
UDPBUF->udplen = HTONS(uip_slen + 8);
UDPBUF->udpchksum = 0;
return;
drop:
uip_len = 0;
return;
}
void uip_udp_periodic(void)
{
if(uip_udp_conn->lport != 0) {
uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
uip_len = uip_slen = 0;
uip_flags = UIP_POLL;
UIP_UDP_APPCALL();
}
if(uip_slen == 0)
{
uip_len = 0;
return;
}
uip_len = uip_slen + 8 + 20;
UDPBUF->vhl = 0x45;
UDPBUF->tos = 0;
UDPBUF->len[0] = (uip_len >> 8);
UDPBUF->len[1] = (uip_len & 0xff);
UDPBUF->ipoffset[0] = UDPBUF->ipoffset[1] = 0;
UDPBUF->ttl = UIP_TTL;
++ipid;
UDPBUF->ipid[0] = ipid >> 8;
UDPBUF->ipid[1] = ipid & 0xff;
UDPBUF->proto = UIP_PROTO_UDP;
UDPBUF->ipchksum = ~(uip_ipchksum());
UDPBUF->srcipaddr[0] = uip_hostaddr[0];
UDPBUF->srcipaddr[1] = uip_hostaddr[1];
UDPBUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
UDPBUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
UDPBUF->srcport = uip_udp_conn->lport;
UDPBUF->destport = uip_udp_conn->rport;
UDPBUF->udplen = HTONS(uip_slen + 8);
UDPBUF->udpchksum = 0;
}
u16_t uip_chksum(u16_t *sdata, u16_t len)
{
u16_t acc;
for (acc = 0; len > 1; len -= 2) {
u16_t u = ((unsigned char *)sdata)[0] + (((unsigned char *)sdata)[1] << 8);
if ((acc += u) < u) {
++acc;
}
++sdata;
}
if(len == 1) {
acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
++acc;
}
}
return acc;
}
u16_t uip_ipchksum(void)
{
return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
}
u16_t htons(u16_t val)
{
return HTONS(val);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -