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