📄 udp.c
字号:
#include <string.h>
#include <ctype.h>
#include "necfg.h"
#include "ne2000.h"
#include "ip.h"
#include "udp.h"
/********************************************************************************************************
* Return UDP data length (-1 if no data), 0 if not UDP *
********************************************************************************************************/
short Is_UDP(IPKT *ip, short len)
{
UDPKT *udp;
unsigned short sum;
short dlen=0;
// Check protocol & minimum length
if (ip->i.pcol==PUDP && len>=sizeof(UDPHDR))
{
udp = (UDPKT *)ip; // Do checksum
sum = Check_UDP(udp, swapl(Get_IP_Srceip(ip)), swapl(Get_IP_Destip(ip)), len);
if (!udp->u.check || sum==0xffff)
{ // If zero or correct..
Swap_UDP(udp); // Do byte-swaps
len -= sizeof(UDPHDR); // Subtract header len
dlen = len>0 ? len : -1; // Return -1 if data len=0
}
}
return(dlen);
}
/********************************************************************************************************
* Make a UDP datagram given the source & destination, data len *
********************************************************************************************************/
short Make_UDP(ETHERFRAME *efp, NODE *srcep, NODE *destp, unsigned short dlen)
{
UDPKT *udp;
short ulen, ilen;
udp = (UDPKT *)(efp->edata);
udp->u.sport = srcep->port; // Set ports
udp->u.dport = destp->port;
udp->u.len = ulen = dlen + sizeof(UDPHDR);
udp->u.check = 0;
Swap_UDP(udp); // Byte-swap
ilen = Make_IP(efp, srcep, destp, PUDP, (unsigned short)(ulen));
udp->u.check = ~Check_UDP(udp, srcep->ip, destp->ip, ulen);
if (udp->u.check == 0) // Change sum of 0 to FFFF
udp->u.check = 0xffff;
return(ilen); // Return IP length
}
/********************************************************************************************************
* Return UDP checksum, given UDP (header + data) length. *
* The values must be in network byte-order *
********************************************************************************************************/
unsigned short Check_UDP(UDPKT *udp, unsigned int sip, unsigned int dip, short ulen)
{
PHDR tph;
unsigned int sum;
sum = csum((unsigned char *)&udp->u, (unsigned short)ulen); // Checksum UDP segment
tph.len = swapw((unsigned short)ulen); // Make pseudo-header
tph.srce = sip;
tph.dest = dip;
tph.z = 0;
tph.pcol = udp->i.pcol;
sum += csum(&tph, sizeof(tph)); // Checksum pseudo-header
return((unsigned short)(sum + (sum >> 16))); // Return total plus carry
}
/********************************************************************************************************
* Swap byte order of ints in TCP header *
********************************************************************************************************/
void Swap_UDP(UDPKT *udp)
{
udp->u.sport = swapw(udp->u.sport);
udp->u.dport = swapw(udp->u.dport);
udp->u.len = swapw(udp->u.len);
}
/********************************************************************************************************
* Get the frame driver type, source port, IP and Ethernet addrs *
********************************************************************************************************/
void Get_UDP_Srce(ETHERFRAME *efp, NODE *np)
{
UDPKT *udp;
memset(np, 0, sizeof(NODE)); // Clear unused fields
Get_IP_Srce(efp, np); // Get dtype, srce IP and Ether addrs
udp = (UDPKT *)(efp->edata);
np->port = udp->u.sport; // Get source port
}
/********************************************************************************************************
* Get the frame driver type, destination port, IP and Ethernet addrs *
********************************************************************************************************/
void Get_UDP_Dest(ETHERFRAME *efp, NODE *np)
{
UDPKT *udp;
memset(np, 0, sizeof(NODE)); // Clear unused fields
Get_IP_Dest(efp, np); // Get dtype, dest IP and Ether addrs
udp = (UDPKT *)(efp->edata);
np->port = udp->u.dport; // Get dest port
}
/********************************************************************************************************
* Make a TPTP Request *
********************************************************************************************************/
short Make_TFTP_Req(ETHERFRAME *efp, NODE *sp, NODE *dp, unsigned short op, char *fname, char *mode)
{
TFTP_REQ *tpr;
unsigned short len;
tpr = (TFTP_REQ *)(efp->edata);
tpr->op = swapw(op);
len = strlen(strcpy((char *)tpr->data, fname)) + 1;
len += strlen(strcpy((char *)&tpr->data[len], mode)) + 1;
return(Make_UDP(efp, sp, dp, (unsigned short)(len+2)));
}
/********************************************************************************************************
* Make a TFPT ACK *
********************************************************************************************************/
short Make_TFTP_Ack(ETHERFRAME *efp, NODE *sp, NODE *dp, unsigned short op, unsigned short block)
{
TFTP_DATA *tpd;
tpd = (TFTP_DATA *)(efp->edata);
tpd->op = swapw(op);
tpd->block = swapw(block);
return(Make_UDP(efp, sp, dp, 4));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -