netinet_in.odin 6.7 KB

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