www.pudn.com > e041tcpipc51.rar > Udp.c


#include  
#include  
#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); 
}