recvfromflags.lc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* include recvfrom_flags1 */
  2. #include "unp.h"## 1 ##src/advio/recvfromflags.c##
  3. #include <sys/param.h> /* ALIGN macro for CMSG_NXTHDR() macro */## 2 ##src/advio/recvfromflags.c##
  4. #ifdef HAVE_SOCKADDR_DL_STRUCT## 3 ##src/advio/recvfromflags.c##
  5. # include <net/if_dl.h>## 4 ##src/advio/recvfromflags.c##
  6. #endif## 5 ##src/advio/recvfromflags.c##
  7. ssize_t## 6 ##src/advio/recvfromflags.c##
  8. recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,## 7 ##src/advio/recvfromflags.c##
  9. SA *sa, socklen_t *salenptr, struct in_pktinfo *pktp)## 8 ##src/advio/recvfromflags.c##
  10. {## 9 ##src/advio/recvfromflags.c##
  11. struct msghdr msg;## 10 ##src/advio/recvfromflags.c##
  12. struct iovec iov[1];## 11 ##src/advio/recvfromflags.c##
  13. ssize_t n;## 12 ##src/advio/recvfromflags.c##
  14. #ifdef HAVE_MSGHDR_MSG_CONTROL## 13 ##src/advio/recvfromflags.c##
  15. struct cmsghdr *cmptr;## 14 ##src/advio/recvfromflags.c##
  16. union {## 15 ##src/advio/recvfromflags.c##
  17. struct cmsghdr cm;## 16 ##src/advio/recvfromflags.c##
  18. char control[CMSG_SPACE(sizeof(struct in_addr)) +## 17 ##src/advio/recvfromflags.c##
  19. CMSG_SPACE(sizeof(struct in_pktinfo))];## 18 ##src/advio/recvfromflags.c##
  20. } control_un;## 19 ##src/advio/recvfromflags.c##
  21. msg.msg_control = control_un.control;## 20 ##src/advio/recvfromflags.c##
  22. msg.msg_controllen = sizeof(control_un.control);## 21 ##src/advio/recvfromflags.c##
  23. msg.msg_flags = 0;## 22 ##src/advio/recvfromflags.c##
  24. #else## 23 ##src/advio/recvfromflags.c##
  25. bzero(&msg, sizeof(msg)); /* make certain msg_accrightslen = 0 */## 24 ##src/advio/recvfromflags.c##
  26. #endif## 25 ##src/advio/recvfromflags.c##
  27. msg.msg_name = sa;## 26 ##src/advio/recvfromflags.c##
  28. msg.msg_namelen = *salenptr;## 27 ##src/advio/recvfromflags.c##
  29. iov[0].iov_base = ptr;## 28 ##src/advio/recvfromflags.c##
  30. iov[0].iov_len = nbytes;## 29 ##src/advio/recvfromflags.c##
  31. msg.msg_iov = iov;## 30 ##src/advio/recvfromflags.c##
  32. msg.msg_iovlen = 1;## 31 ##src/advio/recvfromflags.c##
  33. if ((n = recvmsg(fd, &msg, *flagsp)) < 0)## 32 ##src/advio/recvfromflags.c##
  34. return (n);## 33 ##src/advio/recvfromflags.c##
  35. *salenptr = msg.msg_namelen; /* pass back results */## 34 ##src/advio/recvfromflags.c##
  36. if (pktp)## 35 ##src/advio/recvfromflags.c##
  37. bzero(pktp, sizeof(struct in_pktinfo)); /* 0.0.0.0, i/f = 0 */## 36 ##src/advio/recvfromflags.c##
  38. /* end recvfrom_flags1 */
  39. /* include recvfrom_flags2 */
  40. #ifndef HAVE_MSGHDR_MSG_CONTROL## 37 ##src/advio/recvfromflags.c##
  41. *flagsp = 0; /* pass back results */## 38 ##src/advio/recvfromflags.c##
  42. return (n);## 39 ##src/advio/recvfromflags.c##
  43. #else## 40 ##src/advio/recvfromflags.c##
  44. *flagsp = msg.msg_flags; /* pass back results */## 41 ##src/advio/recvfromflags.c##
  45. if (msg.msg_controllen < sizeof(struct cmsghdr) ||## 42 ##src/advio/recvfromflags.c##
  46. (msg.msg_flags & MSG_CTRUNC) || pktp == NULL)## 43 ##src/advio/recvfromflags.c##
  47. return (n);## 44 ##src/advio/recvfromflags.c##
  48. for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;## 45 ##src/advio/recvfromflags.c##
  49. cmptr = CMSG_NXTHDR(&msg, cmptr)) {## 46 ##src/advio/recvfromflags.c##
  50. #ifdef IP_RECVDSTADDR## 47 ##src/advio/recvfromflags.c##
  51. if (cmptr->cmsg_level == IPPROTO_IP &&## 48 ##src/advio/recvfromflags.c##
  52. cmptr->cmsg_type == IP_RECVDSTADDR) {## 49 ##src/advio/recvfromflags.c##
  53. memcpy(&pktp->ipi_addr, CMSG_DATA(cmptr),## 50 ##src/advio/recvfromflags.c##
  54. sizeof(struct in_addr));## 51 ##src/advio/recvfromflags.c##
  55. continue;## 52 ##src/advio/recvfromflags.c##
  56. }## 53 ##src/advio/recvfromflags.c##
  57. #endif## 54 ##src/advio/recvfromflags.c##
  58. #ifdef IP_RECVIF## 55 ##src/advio/recvfromflags.c##
  59. if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF) {## 56 ##src/advio/recvfromflags.c##
  60. struct sockaddr_dl *sdl;## 57 ##src/advio/recvfromflags.c##
  61. sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr);## 58 ##src/advio/recvfromflags.c##
  62. pktp->ipi_ifindex = sdl->sdl_index;## 59 ##src/advio/recvfromflags.c##
  63. continue;## 60 ##src/advio/recvfromflags.c##
  64. }## 61 ##src/advio/recvfromflags.c##
  65. #endif## 62 ##src/advio/recvfromflags.c##
  66. err_quit("unknown ancillary data, len = %d, level = %d, type = %d",## 63 ##src/advio/recvfromflags.c##
  67. cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type);## 64 ##src/advio/recvfromflags.c##
  68. }## 65 ##src/advio/recvfromflags.c##
  69. return (n);## 66 ##src/advio/recvfromflags.c##
  70. #endif /* HAVE_MSGHDR_MSG_CONTROL */## 67 ##src/advio/recvfromflags.c##
  71. }## 68 ##src/advio/recvfromflags.c##
  72. /* end recvfrom_flags2 */
  73. ssize_t## 69 ##src/advio/recvfromflags.c##
  74. Recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,## 70 ##src/advio/recvfromflags.c##
  75. SA *sa, socklen_t *salenptr, struct in_pktinfo *pktp)## 71 ##src/advio/recvfromflags.c##
  76. {## 72 ##src/advio/recvfromflags.c##
  77. ssize_t n;## 73 ##src/advio/recvfromflags.c##
  78. n = recvfrom_flags(fd, ptr, nbytes, flagsp, sa, salenptr, pktp);## 74 ##src/advio/recvfromflags.c##
  79. if (n < 0)## 75 ##src/advio/recvfromflags.c##
  80. err_quit("recvfrom_flags error");## 76 ##src/advio/recvfromflags.c##
  81. return (n);## 77 ##src/advio/recvfromflags.c##
  82. }## 78 ##src/advio/recvfromflags.c##