netinet_in.odin 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. package posix
  2. import "core:c"
  3. when ODIN_OS == .Darwin {
  4. foreign import lib "system:System.framework"
  5. } else {
  6. foreign import lib "system:c"
  7. }
  8. // netinet/in.h - Internet address family
  9. foreign lib {
  10. in6addr_any: in6_addr
  11. in6addr_loopback: in6_addr
  12. }
  13. in_port_t :: u16be
  14. in_addr_t :: u32be
  15. INET_ADDRSTRLEN :: 16
  16. INET6_ADDRSTRLEN :: 46
  17. Protocol :: enum c.int {
  18. IP = IPPROTO_IP,
  19. ICMP = IPPROTO_ICMP,
  20. IPV6 = IPPROTO_IPV6,
  21. RAW = IPPROTO_RAW,
  22. TCP = IPPROTO_TCP,
  23. UDP = IPPROTO_UDP,
  24. }
  25. when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
  26. in_addr :: struct {
  27. s_addr: in_addr_t, /* [PSX] big endian address */
  28. }
  29. in6_addr :: struct {
  30. using _: struct #raw_union {
  31. s6_addr: [16]c.uint8_t, /* [PSX] big endian address */
  32. __u6_addr16: [8]c.uint16_t,
  33. __u6_addr32: [4]c.uint32_t,
  34. },
  35. }
  36. sockaddr_in :: struct {
  37. sin_len: c.uint8_t,
  38. sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */
  39. sin_port: in_port_t, /* [PSX] port number */
  40. sin_addr: in_addr, /* [PSX] IP address */
  41. sin_zero: [8]c.char,
  42. }
  43. sockaddr_in6 :: struct {
  44. sin6_len: c.uint8_t,
  45. sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */
  46. sin6_port: in_port_t, /* [PSX] port number */
  47. sin6_flowinfo: c.uint32_t, /* [PSX] IPv6 traffic class and flow information */
  48. sin6_addr: in6_addr, /* [PSX] IPv6 address */
  49. sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */
  50. }
  51. ipv6_mreq :: struct {
  52. ipv6mr_multiaddr: in6_addr, /* [PSX] IPv6 multicast address */
  53. ipv6mr_interface: c.uint, /* [PSX] interface index */
  54. }
  55. IPPROTO_IP :: 0
  56. IPPROTO_ICMP :: 1
  57. IPPROTO_IPV6 :: 41
  58. IPPROTO_RAW :: 255
  59. IPPROTO_TCP :: 6
  60. IPPROTO_UDP :: 17
  61. INADDR_ANY :: 0x00000000
  62. INADDR_BROADCAST :: 0xFFFFFFFF
  63. IPV6_JOIN_GROUP :: 12
  64. IPV6_LEAVE_GROUP :: 13
  65. IPV6_MULTICAST_HOPS :: 10
  66. IPV6_MULTICAST_IF :: 9
  67. IPV6_MULTICAST_LOOP :: 11
  68. IPV6_UNICAST_HOPS :: 4
  69. IPV6_V6ONLY :: 27
  70. IN6_IS_ADDR_UNSPECIFIED :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  71. return a.s6_addr == 0
  72. }
  73. IN6_IS_ADDR_LOOPBACK :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  74. a := a
  75. return (
  76. (^c.uint32_t)(&a.s6_addr[0])^ == 0 &&
  77. (^c.uint32_t)(&a.s6_addr[4])^ == 0 &&
  78. (^c.uint32_t)(&a.s6_addr[8])^ == 0 &&
  79. (^u32be)(&a.s6_addr[12])^ == 1 \
  80. )
  81. }
  82. IN6_IS_ADDR_MULTICAST :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  83. return a.s6_addr[0] == 0xff
  84. }
  85. IN6_IS_ADDR_LINKLOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  86. return a.s6_addr[0] == 0xfe && a.s6_addr[1] & 0xc0 == 0x80
  87. }
  88. IN6_IS_ADDR_SITELOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  89. return a.s6_addr[0] == 0xfe && a.s6_addr[1] & 0xc0 == 0xc0
  90. }
  91. IN6_IS_ADDR_V4MAPPED :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  92. a := a
  93. return (
  94. (^c.uint32_t)(&a.s6_addr[0])^ == 0 &&
  95. (^c.uint32_t)(&a.s6_addr[4])^ == 0 &&
  96. (^u32be)(&a.s6_addr[8])^ == 0x0000ffff \
  97. )
  98. }
  99. IN6_IS_ADDR_V4COMPAT :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  100. a := a
  101. return (
  102. (^c.uint32_t)(&a.s6_addr[0])^ == 0 &&
  103. (^c.uint32_t)(&a.s6_addr[4])^ == 0 &&
  104. (^c.uint32_t)(&a.s6_addr[8])^ == 0 &&
  105. (^c.uint32_t)(&a.s6_addr[12])^ != 0 &&
  106. (^u32be)(&a.s6_addr[12])^ != 1 \
  107. )
  108. }
  109. @(private)
  110. __IPV6_ADDR_SCOPE_NODELOCAL :: 0x01
  111. @(private)
  112. __IPV6_ADDR_SCOPE_LINKLOCAL :: 0x02
  113. @(private)
  114. __IPV6_ADDR_SCOPE_SITELOCAL :: 0x05
  115. @(private)
  116. __IPV6_ADDR_SCOPE_ORGLOCAL :: 0x08
  117. @(private)
  118. __IPV6_ADDR_SCOPE_GLOBAL :: 0x0e
  119. @(private)
  120. IPV6_ADDR_MC_FLAGS :: #force_inline proc "contextless" (a: in6_addr) -> c.uint8_t {
  121. return a.s6_addr[1] & 0xf0
  122. }
  123. @(private)
  124. IPV6_ADDR_MC_FLAGS_TRANSIENT :: 0x10
  125. @(private)
  126. IPV6_ADDR_MC_FLAGS_PREFIX :: 0x20
  127. @(private)
  128. IPV6_ADDR_MC_FLAGS_UNICAST_BASED :: IPV6_ADDR_MC_FLAGS_TRANSIENT | IPV6_ADDR_MC_FLAGS_PREFIX
  129. @(private)
  130. __IPV6_ADDR_MC_SCOPE :: #force_inline proc "contextless" (a: in6_addr) -> c.uint8_t {
  131. return a.s6_addr[1] & 0x0f
  132. }
  133. IN6_IS_ADDR_MC_NODELOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  134. return (
  135. IN6_IS_ADDR_MULTICAST(a) &&
  136. (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL) \
  137. )
  138. }
  139. IN6_IS_ADDR_MC_LINKLOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  140. return (
  141. IN6_IS_ADDR_MULTICAST(a) &&
  142. (IPV6_ADDR_MC_FLAGS(a) != IPV6_ADDR_MC_FLAGS_UNICAST_BASED) &&
  143. (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL) \
  144. )
  145. }
  146. IN6_IS_ADDR_MC_SITELOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  147. return (
  148. IN6_IS_ADDR_MULTICAST(a) &&
  149. (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL) \
  150. )
  151. }
  152. IN6_IS_ADDR_MC_ORGLOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  153. return (
  154. IN6_IS_ADDR_MULTICAST(a) &&
  155. (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL) \
  156. )
  157. }
  158. IN6_IS_ADDR_MC_GLOBAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
  159. return (
  160. IN6_IS_ADDR_MULTICAST(a) &&
  161. (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL) \
  162. )
  163. }
  164. } else {
  165. #panic("posix is unimplemented for the current target")
  166. }