1 // socket_linux.go -- Socket handling specific to Linux.
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.
10 // DO NOT USE DIRECTLY.
16 type RawSockaddrInet4
struct {
19 Addr
[4]byte /* in_addr */;
23 type RawSockaddrInet6
struct {
27 Addr
[16]byte /* in6_addr */;
31 type RawSockaddrUnix
struct {
36 type RawSockaddr
struct {
41 func (sa
*SockaddrInet4
) sockaddr() (*RawSockaddrAny
, Socklen_t
, int) {
42 if sa
.Port
< 0 || sa
.Port
> 0xFFFF {
43 return nil, 0, EINVAL
;
45 sa
.raw
.Family
= AF_INET
;
46 p
:= (*[2]byte)(unsafe
.Pointer(&sa
.raw
.Port
));
47 p
[0] = byte(sa
.Port
>>8);
49 for i
:= 0; i
< len(sa
.Addr
); i
++ {
50 sa
.raw
.Addr
[i
] = sa
.Addr
[i
];
52 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), SizeofSockaddrInet4
, 0;
55 func (sa
*SockaddrInet6
) sockaddr() (*RawSockaddrAny
, Socklen_t
, int) {
56 if sa
.Port
< 0 || sa
.Port
> 0xFFFF {
57 return nil, 0, EINVAL
;
59 sa
.raw
.Family
= AF_INET6
;
60 p
:= (*[2]byte)(unsafe
.Pointer(&sa
.raw
.Port
));
61 p
[0] = byte(sa
.Port
>>8);
63 for i
:= 0; i
< len(sa
.Addr
); i
++ {
64 sa
.raw
.Addr
[i
] = sa
.Addr
[i
];
66 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), SizeofSockaddrInet6
, 0;
69 func (sa
*SockaddrUnix
) sockaddr() (*RawSockaddrAny
, Socklen_t
, int) {
72 if n
>= len(sa
.raw
.Path
) || n
== 0 {
73 return nil, 0, EINVAL
;
75 sa
.raw
.Family
= AF_UNIX
;
76 for i
:= 0; i
< n
; i
++ {
77 sa
.raw
.Path
[i
] = int8(name
[i
]);
79 if sa
.raw
.Path
[0] == '@' {
83 // length is family, name, NUL.
84 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), 1 + Socklen_t(n
) + 1, 0;
87 func anyToSockaddr(rsa
*RawSockaddrAny
) (Sockaddr
, int) {
88 switch rsa
.Addr
.Family
{
90 pp
:= (*RawSockaddrUnix
)(unsafe
.Pointer(rsa
));
91 sa
:= new(SockaddrUnix
);
93 // "Abstract" Unix domain socket.
94 // Rewrite leading NUL as @ for textual display.
95 // (This is the standard convention.)
96 // Not friendly to overwrite in place,
97 // but the callers below don't care.
101 // Assume path ends at NUL.
102 // This is not technically the Linux semantics for
103 // abstract Unix domain sockets--they are supposed
104 // to be uninterpreted fixed-size binary blobs--but
105 // everyone uses this convention.
107 for n
< len(pp
.Path
) - 3 && pp
.Path
[n
] != 0 {
110 bytes
:= (*[len(pp
.Path
)]byte)(unsafe
.Pointer(&pp
.Path
[0]));
111 sa
.Name
= string(bytes
[0:n
]);
115 pp
:= (*RawSockaddrInet4
)(unsafe
.Pointer(rsa
));
116 sa
:= new(SockaddrInet4
);
117 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
));
118 sa
.Port
= int(p
[0])<<8 + int(p
[1]);
119 for i
:= 0; i
< len(sa
.Addr
); i
++ {
120 sa
.Addr
[i
] = pp
.Addr
[i
];
125 pp
:= (*RawSockaddrInet6
)(unsafe
.Pointer(rsa
));
126 sa
:= new(SockaddrInet6
);
127 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
));
128 sa
.Port
= int(p
[0])<<8 + int(p
[1]);
129 for i
:= 0; i
< len(sa
.Addr
); i
++ {
130 sa
.Addr
[i
] = pp
.Addr
[i
];
134 return nil, EAFNOSUPPORT
;
137 // BindToDevice binds the socket associated with fd to device.
138 func BindToDevice(fd
int, device
string) (errno
int) {
139 return SetsockoptString(fd
, SOL_SOCKET
, SO_BINDTODEVICE
, device
)