1 // socket_bsd.go -- Socket handling specific to *BSD based systems.
3 // Copyright 2010 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // Low-level socket interface.
8 // Only for implementing net package.
9 // DO NOT USE DIRECTLY.
15 type RawSockaddrInet4 struct {
19 Addr [4]byte /* in_addr */;
23 type RawSockaddrInet6 struct {
28 Addr [16]byte /* in6_addr */;
32 type RawSockaddrUnix struct {
38 type RawSockaddr struct {
44 func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
45 if sa.Port < 0 || sa.Port > 0xFFFF {
46 return nil, 0, EINVAL;
48 sa.raw.Len = SizeofSockaddrInet4;
49 sa.raw.Family = AF_INET;
50 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port));
51 p[0] = byte(sa.Port>>8);
53 for i := 0; i < len(sa.Addr); i++ {
54 sa.raw.Addr[i] = sa.Addr[i];
56 return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), Socklen_t(sa.raw.Len), 0;
59 func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
60 if sa.Port < 0 || sa.Port > 0xFFFF {
61 return nil, 0, EINVAL;
63 sa.raw.Len = SizeofSockaddrInet6;
64 sa.raw.Family = AF_INET6;
65 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port));
66 p[0] = byte(sa.Port>>8);
68 for i := 0; i < len(sa.Addr); i++ {
69 sa.raw.Addr[i] = sa.Addr[i];
71 return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), Socklen_t(sa.raw.Len), 0;
74 func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
77 if n >= len(sa.raw.Path) || n == 0 {
78 return nil, 0, EINVAL;
80 sa.raw.Len = byte(3 + n); // 2 for Family, Len; 1 for NUL.
81 sa.raw.Family = AF_UNIX;
82 for i := 0; i < n; i++ {
83 sa.raw.Path[i] = int8(name[i]);
85 if sa.raw.Path[0] == '@' {
89 // length is family, name, NUL.
90 return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), Socklen_t(sa.raw.Len), 0;
93 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) {
94 switch rsa.Addr.Family {
96 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
97 if pp.Len < 3 || pp.Len > SizeofSockaddrUnix {
100 sa := new(SockaddrUnix)
101 n := int(pp.Len) - 3 // subtract leading Family, Len, terminating NUL.
102 for i := 0; i < n; i++ {
104 // found early NUL; assume Len is overestimating.
109 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))
110 sa.Name = string(bytes[0:n])
114 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa));
115 sa := new(SockaddrInet4);
116 p := (*[2]byte)(unsafe.Pointer(&pp.Port));
117 sa.Port = int(p[0])<<8 + int(p[1]);
118 for i := 0; i < len(sa.Addr); i++ {
119 sa.Addr[i] = pp.Addr[i];
124 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa));
125 sa := new(SockaddrInet6);
126 p := (*[2]byte)(unsafe.Pointer(&pp.Port));
127 sa.Port = int(p[0])<<8 + int(p[1]);
128 for i := 0; i < len(sa.Addr); i++ {
129 sa.Addr[i] = pp.Addr[i];
133 return nil, EAFNOSUPPORT;
136 // BindToDevice binds the socket associated with fd to device.
137 func BindToDevice(fd int, device string) (errno int) {