26
26
%% Primitive inet_drv interface
28
-export([open/1, open/2, fdopen/2, fdopen/3, close/1]).
29
-export([bind/3, listen/1, listen/2]).
28
-export([open/3, fdopen/4, close/1]).
29
-export([bind/3, listen/1, listen/2, peeloff/2]).
30
30
-export([connect/3, connect/4, async_connect/4]).
31
31
-export([accept/1, accept/2, async_accept/2]).
32
32
-export([shutdown/2]).
36
36
-export([recvfrom/2, recvfrom/3]).
37
37
-export([setopt/3, setopts/2, getopt/2, getopts/2, is_sockopt_val/2]).
38
38
-export([chgopt/3, chgopts/2]).
39
-export([getstat/2, getfd/1, getindex/1, getstatus/1, gettype/1,
39
-export([getstat/2, getfd/1, ignorefd/2,
40
getindex/1, getstatus/1, gettype/1,
40
41
getifaddrs/1, getiflist/1, ifget/3, ifset/3,
42
43
-export([getservbyname/3, getservbyport/3]).
57
58
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59
%% OPEN(tcp | udp | sctp, inet | inet6) ->
60
%% OPEN(tcp | udp | sctp, inet | inet6, stream | dgram | seqpacket) ->
60
61
%% {ok, insock()} |
63
64
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65
open(Protocol) -> open1(Protocol, ?INET_AF_INET).
67
open(Protocol, inet) -> open1(Protocol, ?INET_AF_INET);
68
open(Protocol, inet6) -> open1(Protocol, ?INET_AF_INET6);
69
open(_, _) -> {error, einval}.
71
fdopen(Protocol, Fd) -> fdopen1(Protocol, ?INET_AF_INET, Fd).
73
fdopen(Protocol, Fd, inet) -> fdopen1(Protocol, ?INET_AF_INET, Fd);
74
fdopen(Protocol, Fd, inet6) -> fdopen1(Protocol, ?INET_AF_INET6, Fd);
75
fdopen(_, _, _) -> {error, einval}.
77
open1(Protocol, Family) ->
78
case open0(Protocol) of
80
case ctl_cmd(S, ?INET_REQ_OPEN, [Family]) of
89
fdopen1(Protocol, Family, Fd) when is_integer(Fd) ->
90
case open0(Protocol) of
92
case ctl_cmd(S,?INET_REQ_FDOPEN,[Family,?int32(Fd)]) of
94
Error -> close(S), Error
100
try erlang:open_port({spawn_driver,protocol2drv(Protocol)}, [binary]) of
66
open(Protocol, Family, Type) ->
67
open(Protocol, Family, Type, ?INET_REQ_OPEN, []).
69
fdopen(Protocol, Family, Type, Fd) when is_integer(Fd) ->
70
open(Protocol, Family, Type, ?INET_REQ_FDOPEN, ?int32(Fd)).
72
open(Protocol, Family, Type, Req, Data) ->
73
Drv = protocol2drv(Protocol),
74
AF = enc_family(Family),
76
try erlang:open_port({spawn_driver,Drv}, [binary]) of
78
case ctl_cmd(S, Req, [AF,T,Data]) of
103
error:Reason -> {error,Reason}
85
%% The only (?) way to get here is to try to open
86
%% the sctp driver when it does not exist
87
error:badarg -> {error,eprotonosupport}
90
enc_family(inet) -> ?INET_AF_INET;
91
enc_family(inet6) -> ?INET_AF_INET6.
93
enc_type(stream) -> ?INET_TYPE_STREAM;
94
enc_type(dgram) -> ?INET_TYPE_DGRAM;
95
enc_type(seqpacket) -> ?INET_TYPE_SEQPACKET.
106
97
protocol2drv(tcp) -> "tcp_inet";
107
98
protocol2drv(udp) -> "udp_inet";
108
protocol2drv(sctp) -> "sctp_inet";
110
erlang:error(eprotonosupport).
99
protocol2drv(sctp) -> "sctp_inet".
112
101
drv2protocol("tcp_inet") -> tcp;
113
102
drv2protocol("udp_inet") -> udp;
334
323
%% listening) is also accepted:
336
325
listen(S) -> listen(S, ?LISTEN_BACKLOG).
327
listen(S, true) -> listen(S, ?LISTEN_BACKLOG);
328
listen(S, false) -> listen(S, 0);
338
329
listen(S, BackLog) when is_port(S), is_integer(BackLog) ->
339
case ctl_cmd(S, ?TCP_REQ_LISTEN, [?int16(BackLog)]) of
330
case ctl_cmd(S, ?INET_REQ_LISTEN, [?int16(BackLog)]) of
343
listen(S, Flag) when is_port(S), is_boolean(Flag) ->
344
case ctl_cmd(S, ?SCTP_REQ_LISTEN, enc_value(set, bool8, Flag)) of
332
{error,_}=Error -> Error
335
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337
%% PEELOFF(insock(), AssocId) -> {ok,outsock()} | {error, Reason}
339
%% SCTP: Peel off one association into a type stream socket
341
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343
peeloff(S, AssocId) ->
344
case ctl_cmd(S, ?SCTP_REQ_PEELOFF, [?int32(AssocId)]) of
347
{inet_reply,S,Res} -> Res
349
{error,_}=Error -> Error
349
352
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
517
520
{ok, [F, P1,P0 | Addr]} ->
518
521
{IP, _} = get_ip(F, Addr),
519
522
{ok, { IP, ?u16(P1, P0) }};
523
{error,_}=Error -> Error
523
526
setpeername(S, {IP,Port}) when is_port(S) ->
524
527
case ctl_cmd(S, ?INET_REQ_SETPEER, [?int16(Port),ip_to_bytes(IP)]) of
529
{error,_}=Error -> Error
528
531
setpeername(S, undefined) when is_port(S) ->
529
532
case ctl_cmd(S, ?INET_REQ_SETPEER, []) of
534
{error,_}=Error -> Error
534
537
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
542
545
{ok, [F, P1, P0 | Addr]} ->
543
546
{IP, _} = get_ip(F, Addr),
544
547
{ok, { IP, ?u16(P1, P0) }};
548
{error,_}=Error -> Error
548
551
setsockname(S, {IP,Port}) when is_port(S) ->
549
552
case ctl_cmd(S, ?INET_REQ_SETNAME, [?int16(Port),ip_to_bytes(IP)]) of
554
{error,_}=Error -> Error
553
556
setsockname(S, undefined) when is_port(S) ->
554
557
case ctl_cmd(S, ?INET_REQ_SETNAME, []) of
559
{error,_}=Error -> Error
559
562
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835
838
getfd(S) when is_port(S) ->
836
839
case ctl_cmd(S, ?INET_REQ_GETFD, []) of
837
840
{ok, [S3,S2,S1,S0]} -> {ok, ?u32(S3,S2,S1,S0)};
841
{error,_}=Error -> Error
841
844
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
846
%% IGNOREFD(insock(),boolean()) -> {ok,integer()} | {error, Reason}
848
%% steal internal file descriptor
850
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852
ignorefd(S,Bool) when is_port(S) ->
853
Val = if Bool -> 1; true -> 0 end,
854
case ctl_cmd(S, ?INET_REQ_IGNOREFD, [Val]) of
859
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843
861
%% GETIX(insock()) -> {ok,integer()} | {error, Reason}
845
863
%% get internal socket index
1518
1536
[?INET_AF_INET,?int16(Port)|ip4_to_bytes(IP)];
1519
1537
enc_value_2(addr, {IP,Port}) when tuple_size(IP) =:= 8 ->
1520
1538
[?INET_AF_INET6,?int16(Port)|ip6_to_bytes(IP)];
1521
enc_value_2(ether, [X1,X2,X3,X4,X5,X6]) -> [X1,X2,X3,X4,X5,X6];
1539
enc_value_2(ether, [_,_,_,_,_,_]=Xs) -> Xs;
1522
1540
enc_value_2(sockaddr, any) ->
1523
1541
[?INET_AF_ANY];
1524
1542
enc_value_2(sockaddr, loopback) ->
1572
1590
Val -> {Val, T}
1574
1592
dec_value(ip, [A,B,C,D|T]) -> {{A,B,C,D}, T};
1575
dec_value(ether,[X1,X2,X3,X4,X5,X6|T]) -> {[X1,X2,X3,X4,X5,X6],T};
1593
%% dec_value(ether, [X1,X2,X3,X4,X5,X6|T]) -> {[X1,X2,X3,X4,X5,X6],T};
1576
1594
dec_value(sockaddr, [X|T]) ->
1578
1596
dec_value(linkaddr, [X1,X0|T]) ->