netinet_in.odin 6.1 KB

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