📄 udp.c
字号:
#include <stdio.h>
#include <string.h>
#include "ethernet.h"
#include "ip.h"
#include "udp.h"
/* Return UDP data length (-1 if no data), 0 if not UDP */
int is_udp(IPKT *ip, int len)
{
UDPKT *udp;
WORD sum;
int dlen=0;
/* Check protocol & minimum length */
if (ip->i.pcol==PUDP && len>=sizeof(UDPHDR))
{
udp = (UDPKT *)ip; /* Do checksum */
sum = check_udp(udp, ip->i.sip, ip->i.dip, len);
if (!udp->u.check || sum==0xffff)
{ /* If zero or correct.. */
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 */
int make_udp(ETHERFRAME * efp, NODE *srcep, NODE *destp, WORD dlen)
{
UDPKT *udp;
int ulen, ilen;
udp = (UDPKT *)(efp->edata);
udp->u.sport = srcep->port; /* Set ports */
udp->u.dport = destp->port;
ulen = dlen + sizeof(UDPHDR);
udp->u.len = ulen;
udp->u.check = 0;
ilen = make_ip(efp, srcep, destp, PUDP, (WORD)(ulen));
udp->u.check = ~check_udp(udp, udp->i.sip, udp->i.dip, ulen);
if (udp->u.check == 0) /* Change sum of 0 to FFFF */
udp->u.check = 0xffff;
return(ilen); /* Return IP length */
}
/* Return TCP checksum, given UDP (header + data) length.
** The values must be in network byte-order */
WORD check_udp(UDPKT *udp, LWORD sip, LWORD dip, int ulen)
{
PHDR tph;
LWORD sum;
sum = csum(&udp->u, (WORD)ulen); /* Checksum TCP segment */
tph.len=ulen;
tph.srce = sip;
tph.dest = dip;
tph.z = 0;
tph.pcol = udp->i.pcol;
sum += csum(&tph, sizeof(tph)); /* Checksum pseudo-header */
return((WORD)(sum + (sum /0x10000))); /* Return total plus carry */
}
/* Send a UDP datagram, given destination node, data and length */
void udp_transmit(ETHERFRAME *efp, NODE *sp, NODE *dp, void *dat, int len)
{
UDPKT *udp;
udp = (UDPKT *)efp->edata;
memmove(udp->udpdata, dat, len);
put_ethernet(efp, make_udp(efp, sp, dp, (WORD)max(len, 0)));
}
/* Get the frame driver type, source port, IP and Ethernet addrs */
void getudp_srce(ETHERFRAME *efp, NODE *np)
{
UDPKT *udp;
memset(np, 0, sizeof(NODE)); /* Clear unused fields */
getip_srce(efp, np); /* Get dtype, srce IP and Ether addrs */
udp = (UDPKT *)(efp->edata);
np->port = udp->u.sport; /* Get source port */
}
/* Get complete TCP local node data corresponding to frame dest IP address
** Return 0 if no matching node */
int getudp_locdest(ETHERFRAME *efp, NODE *np)
{
UDPKT *udp;
int ok;
ok = getip_locdest(efp, np); /* Get addresses, dtype & netmask */
udp = (UDPKT *)(efp->edata); /* Get dest port */
np->port = udp->u.dport;
return(ok);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -