ga_aistruct.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "gai_hdr.h"
  2. /*
  3. * Create and fill in an addrinfo{}.
  4. */
  5. /* include ga_aistruct1 */
  6. int
  7. ga_aistruct(struct addrinfo ***paipnext, const struct addrinfo *hintsp,
  8. const void *addr, int family)
  9. {
  10. struct addrinfo *ai;
  11. if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL)
  12. return(EAI_MEMORY);
  13. ai->ai_next = NULL;
  14. ai->ai_canonname = NULL;
  15. **paipnext = ai;
  16. *paipnext = &ai->ai_next;
  17. if ( (ai->ai_socktype = hintsp->ai_socktype) == 0)
  18. ai->ai_flags |= AI_CLONE;
  19. ai->ai_protocol = hintsp->ai_protocol;
  20. /* end ga_aistruct1 */
  21. /* include ga_aistruct2 */
  22. switch ((ai->ai_family = family)) {
  23. #ifdef IPv4
  24. case AF_INET: {
  25. struct sockaddr_in *sinptr;
  26. /* 4allocate sockaddr_in{} and fill in all but port */
  27. if ( (sinptr = calloc(1, sizeof(struct sockaddr_in))) == NULL)
  28. return(EAI_MEMORY);
  29. #ifdef HAVE_SOCKADDR_SA_LEN
  30. sinptr->sin_len = sizeof(struct sockaddr_in);
  31. #endif
  32. sinptr->sin_family = AF_INET;
  33. memcpy(&sinptr->sin_addr, addr, sizeof(struct in_addr));
  34. ai->ai_addr = (struct sockaddr *) sinptr;
  35. ai->ai_addrlen = sizeof(struct sockaddr_in);
  36. break;
  37. }
  38. #endif /* IPV4 */
  39. #ifdef IPv6
  40. case AF_INET6: {
  41. struct sockaddr_in6 *sin6ptr;
  42. /* 4allocate sockaddr_in6{} and fill in all but port */
  43. if ( (sin6ptr = calloc(1, sizeof(struct sockaddr_in6))) == NULL)
  44. return(EAI_MEMORY);
  45. #ifdef HAVE_SOCKADDR_SA_LEN
  46. sin6ptr->sin6_len = sizeof(struct sockaddr_in6);
  47. #endif
  48. sin6ptr->sin6_family = AF_INET6;
  49. memcpy(&sin6ptr->sin6_addr, addr, sizeof(struct in6_addr));
  50. ai->ai_addr = (struct sockaddr *) sin6ptr;
  51. ai->ai_addrlen = sizeof(struct sockaddr_in6);
  52. break;
  53. }
  54. #endif /* IPV6 */
  55. #ifdef UNIXdomain
  56. case AF_LOCAL: {
  57. struct sockaddr_un *unp;
  58. /* 4allocate sockaddr_un{} and fill in */
  59. /* *INDENT-OFF* */
  60. if (strlen(addr) >= sizeof(unp->sun_path))
  61. return(EAI_SERVICE);
  62. if ( (unp = calloc(1, sizeof(struct sockaddr_un))) == NULL)
  63. return(EAI_MEMORY);
  64. /* *INDENT-ON* */
  65. unp->sun_family = AF_LOCAL;
  66. strcpy(unp->sun_path, addr);
  67. #ifdef HAVE_SOCKADDR_SA_LEN
  68. unp->sun_len = SUN_LEN(unp);
  69. #endif
  70. ai->ai_addr = (struct sockaddr *) unp;
  71. ai->ai_addrlen = sizeof(struct sockaddr_un);
  72. if (hintsp->ai_flags & AI_PASSIVE)
  73. unlink(unp->sun_path); /* OK if this fails */
  74. break;
  75. }
  76. #endif /* UNIXDOMAIN */
  77. }
  78. return(0);
  79. }
  80. /* end ga_aistruct2 */