# /* udp_write.c */ /* EMACS_MODES: c !fill */ /* User Datagram Protocol layer for the UNIX network system. The * following routines are included: * udp_write send a udp packet */ #include udp_write (fd, buf, datalen) /* Write the specified packet out to the specified net connection. * The buf argument is a pointer to a packet buffer as allocated by * udp_alloc (). The write routine assumes that the foreign address * (in the packet's internet header) and the local and foreign sockets * (in the udp header) have been filled by the caller. It fills in the * rest of the udp header, including checksumming; then writes it out. * Returns the number of bytes written if successful; if not, returns * -1 and errno contains the error code. * * Arguments: */ int fd; /* the file descriptor */ caddr_t buf; /* packet buffer */ int datalen; /* data length */ { struct udpph ph; /* pseudo-header for checksum */ reg struct udp *pup; /* udp packet */ reg struct ip *pip; /* internet packet */ reg int udplen; /* udp packet length */ caddr_t pdata; /* data portion of udp packet */ extern in_name mymach; /* my internet addr (from in layer) */ pip = in_head(buf); /* get internet */ pup = in_data(pip); /* and udp headers */ pup->ud_len = udplen = datalen + sizeof (struct udp); if (udplen & 1) { /* goddam odd byte count */ pdata = (char *)(pup); /* pad to even byte count */ pdata[udplen] = 0; } #ifndef BIGINDIAN udpswab (pup); /* swap bytes if needed */ #endif ph.ph_src = mymach; /* set up pseudo-header */ ph.ph_dest = pip->ip_dest; ph.ph_zero = 0; ph.ph_prot = UDPPROT; ph.ph_len = pup->ud_len; pup->ud_cksum = cksum (&ph, sizeof (ph) >> 1, 0); /* slight kludge*/ if (udplen > BIGCKSUM) /* fast cksum routine better? */ pup->ud_cksum = ~fcksum (pup, (udplen + 1) >> 1, 0); else pup->ud_cksum = ~cksum (pup, (udplen + 1) >> 1, 0); pip->ip_prot = UDPPROT; pip->ip_tsrv = IP_TSRV; return (in_write (fd, buf, udplen)); }