1// Copyright 2022 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package unix
6
7import (
8	"internal/abi"
9	"syscall"
10	"unsafe"
11)
12
13const (
14	AI_CANONNAME = 0x2
15	AI_ALL       = 0x100
16	AI_V4MAPPED  = 0x800
17	AI_MASK      = 0x1407
18
19	EAI_AGAIN    = 2
20	EAI_NODATA   = 7
21	EAI_NONAME   = 8
22	EAI_SERVICE  = 9
23	EAI_SYSTEM   = 11
24	EAI_OVERFLOW = 14
25
26	NI_NAMEREQD = 4
27)
28
29type Addrinfo struct {
30	Flags     int32
31	Family    int32
32	Socktype  int32
33	Protocol  int32
34	Addrlen   uint32
35	Canonname *byte
36	Addr      *syscall.RawSockaddr
37	Next      *Addrinfo
38}
39
40//go:cgo_ldflag "-lresolv"
41
42//go:cgo_import_dynamic libc_getaddrinfo getaddrinfo "/usr/lib/libSystem.B.dylib"
43func libc_getaddrinfo_trampoline()
44
45func Getaddrinfo(hostname, servname *byte, hints *Addrinfo, res **Addrinfo) (int, error) {
46	gerrno, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_getaddrinfo_trampoline),
47		uintptr(unsafe.Pointer(hostname)),
48		uintptr(unsafe.Pointer(servname)),
49		uintptr(unsafe.Pointer(hints)),
50		uintptr(unsafe.Pointer(res)),
51		0,
52		0)
53	var err error
54	if errno != 0 {
55		err = errno
56	}
57	return int(gerrno), err
58}
59
60//go:cgo_import_dynamic libc_freeaddrinfo freeaddrinfo "/usr/lib/libSystem.B.dylib"
61func libc_freeaddrinfo_trampoline()
62
63func Freeaddrinfo(ai *Addrinfo) {
64	syscall_syscall6(abi.FuncPCABI0(libc_freeaddrinfo_trampoline),
65		uintptr(unsafe.Pointer(ai)),
66		0, 0, 0, 0, 0)
67}
68
69//go:cgo_import_dynamic libc_getnameinfo getnameinfo "/usr/lib/libSystem.B.dylib"
70func libc_getnameinfo_trampoline()
71
72func Getnameinfo(sa *syscall.RawSockaddr, salen int, host *byte, hostlen int, serv *byte, servlen int, flags int) (int, error) {
73	gerrno, _, errno := syscall_syscall9(abi.FuncPCABI0(libc_getnameinfo_trampoline),
74		uintptr(unsafe.Pointer(sa)),
75		uintptr(salen),
76		uintptr(unsafe.Pointer(host)),
77		uintptr(hostlen),
78		uintptr(unsafe.Pointer(serv)),
79		uintptr(servlen),
80		uintptr(flags),
81		0,
82		0)
83	var err error
84	if errno != 0 {
85		err = errno
86	}
87	return int(gerrno), err
88}
89
90//go:cgo_import_dynamic libc_gai_strerror gai_strerror "/usr/lib/libSystem.B.dylib"
91func libc_gai_strerror_trampoline()
92
93func GaiStrerror(ecode int) string {
94	r1, _, _ := syscall_syscall(abi.FuncPCABI0(libc_gai_strerror_trampoline),
95		uintptr(ecode),
96		0, 0)
97	return GoString((*byte)(unsafe.Pointer(r1)))
98}
99
100// Implemented in the runtime package.
101func gostring(*byte) string
102
103func GoString(p *byte) string {
104	return gostring(p)
105}
106
107//go:linkname syscall_syscall syscall.syscall
108func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
109
110//go:linkname syscall_syscallPtr syscall.syscallPtr
111func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
112
113//go:linkname syscall_syscall6 syscall.syscall6
114func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
115
116//go:linkname syscall_syscall6X syscall.syscall6X
117func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
118
119//go:linkname syscall_syscall9 syscall.syscall9
120func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
121
122type ResState struct {
123	unexported [69]uintptr
124}
125
126//go:cgo_import_dynamic libresolv_res_9_ninit res_9_ninit "/usr/lib/libresolv.9.dylib"
127func libresolv_res_9_ninit_trampoline()
128
129func ResNinit(state *ResState) error {
130	_, _, errno := syscall_syscall(abi.FuncPCABI0(libresolv_res_9_ninit_trampoline),
131		uintptr(unsafe.Pointer(state)),
132		0, 0)
133	if errno != 0 {
134		return errno
135	}
136	return nil
137}
138
139//go:cgo_import_dynamic libresolv_res_9_nclose res_9_nclose "/usr/lib/libresolv.9.dylib"
140func libresolv_res_9_nclose_trampoline()
141
142func ResNclose(state *ResState) {
143	syscall_syscall(abi.FuncPCABI0(libresolv_res_9_nclose_trampoline),
144		uintptr(unsafe.Pointer(state)),
145		0, 0)
146}
147
148//go:cgo_import_dynamic libresolv_res_9_nsearch res_9_nsearch "/usr/lib/libresolv.9.dylib"
149func libresolv_res_9_nsearch_trampoline()
150
151func ResNsearch(state *ResState, dname *byte, class, typ int, ans *byte, anslen int) (int, error) {
152	r1, _, errno := syscall_syscall6(abi.FuncPCABI0(libresolv_res_9_nsearch_trampoline),
153		uintptr(unsafe.Pointer(state)),
154		uintptr(unsafe.Pointer(dname)),
155		uintptr(class),
156		uintptr(typ),
157		uintptr(unsafe.Pointer(ans)),
158		uintptr(anslen))
159	if errno != 0 {
160		return 0, errno
161	}
162	return int(int32(r1)), nil
163}
164