udpwrite.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #include "udpcksum.h"
  2. /* include open_output_raw */
  3. int rawfd; /* raw socket to write on */
  4. void
  5. open_output(void)
  6. {
  7. int on=1;
  8. /*
  9. * Need a raw socket to write our own IP datagrams to.
  10. * Process must have superuser privileges to create this socket.
  11. * Also must set IP_HDRINCL so we can write our own IP headers.
  12. */
  13. rawfd = Socket(dest->sa_family, SOCK_RAW, 0);
  14. Setsockopt(rawfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));
  15. }
  16. /* end open_output_raw */
  17. /*
  18. * "buf" points to an empty IP/UDP header,
  19. * followed by "ulen" bytes of user data.
  20. */
  21. /* include udp_write */
  22. void
  23. udp_write(char *buf, int userlen)
  24. {
  25. struct udpiphdr *ui;
  26. struct ip *ip;
  27. /* 4fill in and checksum UDP header */
  28. ip = (struct ip *) buf;
  29. ui = (struct udpiphdr *) buf;
  30. bzero(ui, sizeof(*ui));
  31. /* 8add 8 to userlen for pseudoheader length */
  32. ui->ui_len = htons((uint16_t) (sizeof(struct udphdr) + userlen));
  33. /* 8then add 28 for IP datagram length */
  34. userlen += sizeof(struct udpiphdr);
  35. ui->ui_pr = IPPROTO_UDP;
  36. ui->ui_src.s_addr = ((struct sockaddr_in *) local)->sin_addr.s_addr;
  37. ui->ui_dst.s_addr = ((struct sockaddr_in *) dest)->sin_addr.s_addr;
  38. ui->ui_sport = ((struct sockaddr_in *) local)->sin_port;
  39. ui->ui_dport = ((struct sockaddr_in *) dest)->sin_port;
  40. ui->ui_ulen = ui->ui_len;
  41. if (zerosum == 0) {
  42. #if 1 /* change to if 0 for Solaris 2.x, x < 6 */
  43. if ( (ui->ui_sum = in_cksum((u_int16_t *) ui, userlen)) == 0)
  44. ui->ui_sum = 0xffff;
  45. #else
  46. ui->ui_sum = ui->ui_len;
  47. #endif
  48. }
  49. /* 4fill in rest of IP header; */
  50. /* 4ip_output() calcuates & stores IP header checksum */
  51. ip->ip_v = IPVERSION;
  52. ip->ip_hl = sizeof(struct ip) >> 2;
  53. ip->ip_tos = 0;
  54. #if defined(linux) || defined(__OpenBSD__)
  55. ip->ip_len = htons(userlen); /* network byte order */
  56. #else
  57. ip->ip_len = userlen; /* host byte order */
  58. #endif
  59. ip->ip_id = 0; /* let IP set this */
  60. ip->ip_off = 0; /* frag offset, MF and DF flags */
  61. ip->ip_ttl = TTL_OUT;
  62. Sendto(rawfd, buf, userlen, 0, dest, destlen);
  63. }
  64. /* end udp_write */