Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 496 lines (423 sloc) 13.075 kB
d0508b2 @msantos Convert socket parameters to integers
authored
1 %% Copyright (c) 2010-2011, Michael Santos <michael.santos@gmail.com>
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
2 %% All rights reserved.
3 %%
4 %% Redistribution and use in source and binary forms, with or without
5 %% modification, are permitted provided that the following conditions
6 %% are met:
7 %%
8 %% Redistributions of source code must retain the above copyright
9 %% notice, this list of conditions and the following disclaimer.
10 %%
11 %% Redistributions in binary form must reproduce the above copyright
12 %% notice, this list of conditions and the following disclaimer in the
13 %% documentation and/or other materials provided with the distribution.
14 %%
15 %% Neither the name of the author nor the names of its contributors
16 %% may be used to endorse or promote products derived from this software
17 %% without specific prior written permission.
18 %%
19 %% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 %% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 %% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 %% FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 %% COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 %% INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 %% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 %% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 %% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 %% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 %% ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 %% POSSIBILITY OF SUCH DAMAGE.
31 -module(procket).
560517c @msantos Communicate with Unix sockets
authored
32 -include("procket.hrl").
2a30b69 @msantos Figure out how to run procket setuid helper
authored
33 -include_lib("kernel/include/file.hrl").
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
34
194feb8 @msantos Add NIF versions of recvfrom/sendto
authored
35 -export([
fe09a25 @msantos Remove close/2; add listen/1
authored
36 init/0,
37 open/1,open/2,
a1310c1 @msantos Convenience fun to open character devices
authored
38 dev/1,
fe09a25 @msantos Remove close/2; add listen/1
authored
39 socket/3,
40 listen/1,listen/2,
41 connect/2,
560517c @msantos Communicate with Unix sockets
authored
42 accept/1,accept/2,
fe09a25 @msantos Remove close/2; add listen/1
authored
43 close/1,
3206498 @msantos recvfrom/4: return socket address
authored
44 recv/2,recvfrom/2,recvfrom/4,
2200494 @msantos Add sendto/2,3
authored
45 sendto/2, sendto/3,sendto/4,
eb432ee Add writev() support
Gregory Haskins authored
46 read/2, write/2, writev/2,
fe09a25 @msantos Remove close/2; add listen/1
authored
47 bind/2,
48 ioctl/3,
61b1302 @msantos Allocate pointers to buffers for ioctl requests
authored
49 setsockopt/4,
561469d @msantos Add support for getsockname(2)
authored
50 getsockname/2,
61b1302 @msantos Allocate pointers to buffers for ioctl requests
authored
51
52 alloc/1,
53 buf/1,
7a64070 @msantos Return POSIX atom on error from forked setuid bin
authored
54 memcpy/2,
06dfd93 @msantos Align structure used for LSF on a word
authored
55 wordalign/1, wordalign/2,
7a64070 @msantos Return POSIX atom on error from forked setuid bin
authored
56
57 errno_id/1
194feb8 @msantos Add NIF versions of recvfrom/sendto
authored
58 ]).
dd34004 @msantos Initial support for BPF on BSDs
authored
59 -export([
60 unix_path_max/0,
61 sockaddr_common/2,
62 ntohl/1,
63 ntohs/1
64 ]).
2a30b69 @msantos Figure out how to run procket setuid helper
authored
65 % for debugging
66 -export([
67 get_progname/2,
68 make_cli_args/1,
69 progname/0
70 ]).
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
71
72 -on_load(on_load/0).
73
5d8600f @msantos Dynamically create path to NIF relative to module.
authored
74
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
75 init() ->
76 on_load().
77
78 on_load() ->
5bbc1bb @msantos Dynamically create path to procket executable too.
authored
79 erlang:load_nif(progname(), []).
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
80
81
2a30b69 @msantos Figure out how to run procket setuid helper
authored
82 %%--------------------------------------------------------------------
83 %%% NIF Stubs
84 %%--------------------------------------------------------------------
d7487f7 @msantos Close any file descriptor
authored
85 close(_) ->
86 erlang:error(not_implemented).
87
560517c @msantos Communicate with Unix sockets
authored
88 fdrecv(_) ->
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
89 erlang:error(not_implemented).
90
560517c @msantos Communicate with Unix sockets
authored
91 accept(Socket) ->
f5dc15a @msantos Return socket address from accept/2
authored
92 case accept(Socket, 0) of
93 {ok, FD, <<>>} -> {ok, FD};
94 Error -> Error
95 end.
560517c @msantos Communicate with Unix sockets
authored
96 accept(_,_) ->
97 erlang:error(not_implemented).
98
74a854e @msantos Add sendto/4 and bind/2
authored
99 bind(_,_) ->
100 erlang:error(not_implemented).
101
560517c @msantos Communicate with Unix sockets
authored
102 connect(_,_) ->
103 erlang:error(not_implemented).
104
fe09a25 @msantos Remove close/2; add listen/1
authored
105 listen(Socket) when is_integer(Socket) ->
106 listen(Socket, ?BACKLOG).
560517c @msantos Communicate with Unix sockets
authored
107 listen(_,_) ->
108 erlang:error(not_implemented).
109
3206498 @msantos recvfrom/4: return socket address
authored
110 recv(Socket,Size) ->
111 recvfrom(Socket,Size).
112 recvfrom(Socket,Size) ->
113 case recvfrom(Socket, Size, 0, 0) of
114 {ok, Buf, <<>>} -> {ok, Buf};
115 Error -> Error
116 end.
117 recvfrom(_,_,_,_) ->
194feb8 @msantos Add NIF versions of recvfrom/sendto
authored
118 erlang:error(not_implemented).
119
dd34004 @msantos Initial support for BPF on BSDs
authored
120 read(_,_) ->
121 erlang:error(not_implemented).
122
d0508b2 @msantos Convert socket parameters to integers
authored
123 socket(Family, Type, Protocol) ->
124 socket_nif(maybe_atom(family, Family),
125 maybe_atom(type, Type),
126 maybe_atom(protocol, Protocol)).
d1b85c6 @msantos Fix for atom socket arguments
authored
127 socket_nif(_,_,_) ->
560517c @msantos Communicate with Unix sockets
authored
128 erlang:error(not_implemented).
129
65a61dc @msantos Add an NIF interface to ioctl()
authored
130 ioctl(_,_,_) ->
131 erlang:error(not_implemented).
61b1302 @msantos Allocate pointers to buffers for ioctl requests
authored
132 alloc(_) ->
133 erlang:error(not_implemented).
134 buf(_) ->
135 erlang:error(not_implemented).
136 memcpy(_,_) ->
137 erlang:error(not_implemented).
65a61dc @msantos Add an NIF interface to ioctl()
authored
138
2200494 @msantos Add sendto/2,3
authored
139 sendto(Socket, Buf) ->
140 sendto(Socket, Buf, 0, <<>>).
141 sendto(Socket, Buf, Flags) ->
142 sendto(Socket, Buf, Flags, <<>>).
74a854e @msantos Add sendto/4 and bind/2
authored
143 sendto(_,_,_,_) ->
194feb8 @msantos Add NIF versions of recvfrom/sendto
authored
144 erlang:error(not_implemented).
145
65cd104 @msantos Document NIF interface
authored
146 write(FD, Buf) when is_binary(Buf) ->
147 write_nif(FD, Buf);
148 write(FD, Buf) when is_list(Buf) ->
149 writev(FD, Buf).
150
151 write_nif(_,_) ->
dd34004 @msantos Initial support for BPF on BSDs
authored
152 erlang:error(not_implemented).
65cd104 @msantos Document NIF interface
authored
153
eb432ee Add writev() support
Gregory Haskins authored
154 writev(_,_) ->
155 erlang:error(not_implemented).
dd34004 @msantos Initial support for BPF on BSDs
authored
156
3649b5c @msantos Add an NIF setsockopt for promiscous mode
authored
157 setsockopt(_,_,_,_) ->
158 erlang:error(not_implemented).
159
561469d @msantos Add support for getsockname(2)
authored
160 getsockname(_,_) ->
161 erlang:error(not_implemented).
162
7a64070 @msantos Return POSIX atom on error from forked setuid bin
authored
163 errno_id(_) ->
164 erlang:error(not_implemented).
165
560517c @msantos Communicate with Unix sockets
authored
166
2a30b69 @msantos Figure out how to run procket setuid helper
authored
167 %%--------------------------------------------------------------------
168 %%% Setuid helper
169 %%--------------------------------------------------------------------
a1310c1 @msantos Convenience fun to open character devices
authored
170 dev(Dev) when is_list(Dev) ->
171 open(0, [{dev, Dev}]).
172
560517c @msantos Communicate with Unix sockets
authored
173 open(Port) ->
174 open(Port, []).
175 open(Port, Options) when is_integer(Port), is_list(Options) ->
2a30b69 @msantos Figure out how to run procket setuid helper
authored
176 Progname = get_progname(progname(), Options),
177 {Tmpdir, Pipe} = make_unix_socket_path(Options),
178 Cmd = make_cli_args([
179 {progname, Progname},
180 {port, Port},
181 {pipe, Pipe}
182 ] ++ Options),
183
184 Result = case fdopen(Pipe) of
185 {ok, FD} ->
186 Socket = exec(FD, Cmd),
187 close(FD),
188 Socket;
189 Error ->
190 Error
c31194d @yamt use sudo only when necessary
yamt authored
191 end,
2a30b69 @msantos Figure out how to run procket setuid helper
authored
192
193 cleanup_unix_socket(Tmpdir, Pipe),
c31194d @yamt use sudo only when necessary
yamt authored
194 Result.
cfafb55 @msantos Clean up local socket temp directory
authored
195
2a30b69 @msantos Figure out how to run procket setuid helper
authored
196 % Figure out how the procket helper should be called.
197 get_progname(Progname, Options) ->
198 get_progname(progname, Progname, Options).
c31194d @yamt use sudo only when necessary
yamt authored
199
2a30b69 @msantos Figure out how to run procket setuid helper
authored
200 % Caller has passed in a path?
201 get_progname(progname, Default, Options) ->
202 case proplists:get_value(progname, Options) of
203 undefined ->
204 get_progname(setuid, Default, Options);
205 Progname ->
206 Progname
207 end;
208
209 % Is the default executable setuid/setgid?
210 get_progname(setuid, Progname, Options) ->
211 case file:read_file_info(Progname) of
212 {ok, #file_info{mode = Mode}} ->
213 if
214 % setuid
215 Mode band 16#800 =:= 16#800 ->
216 Progname;
217 % setgid
218 Mode band 16#400 =:= 16#400 ->
219 Progname;
220 true ->
221 get_progname(dev, Progname, Options)
222 end
223 end;
224
225 % Device requested and accessible?
226 get_progname(dev, Progname, Options) ->
227 case proplists:get_value(dev, Options) of
228 undefined ->
229 get_progname(sudo, Progname, Options);
230 Dev ->
231 case file:read_file_info(Dev) of
232 {ok, #file_info{access = read_write}} ->
233 Progname;
234 {ok, _} ->
235 get_progname(sudo, Progname, Options);
236 Error ->
237 Error
238 end
239 end;
240
241 % Fall back to sudo
242 get_progname(sudo, Progname, _Options) ->
243 "sudo " ++ Progname.
244
245 % Run the setuid helper
246 exec(FD, Cmd) ->
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
247 case os:cmd(Cmd) of
7a64070 @msantos Return POSIX atom on error from forked setuid bin
authored
248 "0" ->
2a30b69 @msantos Figure out how to run procket setuid helper
authored
249 fdget(FD);
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
250 Error ->
7a64070 @msantos Return POSIX atom on error from forked setuid bin
authored
251 {error, errno_id(list_to_integer(Error))}
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
252 end.
253
2a30b69 @msantos Figure out how to run procket setuid helper
authored
254 % Unix socket handling: retrieves the fd from the setuid helper
255 make_unix_socket_path(Options) ->
256 {Tmpdir, Socket} = case proplists:get_value(pipe, Options) of
257 undefined ->
258 Tmp = procket_mktmp:dirname(),
259 ok = procket_mktmp:make_dir(Tmp),
260 Path = Tmp ++ "/sock",
261 {Tmp, Path};
262 Path ->
263 {false, Path}
264 end,
265 {Tmpdir, Socket}.
266
267 cleanup_unix_socket(false, Pipe) ->
268 file:delete(Pipe);
269 cleanup_unix_socket(Tmpdir, Pipe) ->
270 file:delete(Pipe),
271 procket_mktmp:close(Tmpdir).
cfafb55 @msantos Clean up local socket temp directory
authored
272
560517c @msantos Communicate with Unix sockets
authored
273 fdopen(Path) when is_list(Path) ->
274 fdopen(list_to_binary(Path));
275 fdopen(Path) when is_binary(Path), byte_size(Path) < ?UNIX_PATH_MAX ->
276 {ok, Socket} = socket(?PF_LOCAL, ?SOCK_STREAM, 0),
6dcac8f @msantos Fix sockaddr on BSD
authored
277 Len = byte_size(Path),
278 Sun = <<(sockaddr_common(?PF_LOCAL, Len))/binary,
279 Path/binary,
280 0:((unix_path_max()-Len)*8)
281 >>,
560517c @msantos Communicate with Unix sockets
authored
282 ok = bind(Socket, Sun),
283 ok = listen(Socket, ?BACKLOG),
284 {ok, Socket}.
285
286 fdget(Socket) ->
287 {ok, S} = accept(Socket),
288 fdrecv(S).
289
2a30b69 @msantos Figure out how to run procket setuid helper
authored
290 % Construct the cli arguments for the helper
291 make_cli_args(Options) ->
292 {[[{progname,Progname}|_],
293 IPaddrs], Rest} = proplists:split(Options, [progname, ip]),
294 IP = case IPaddrs of
295 [] -> [];
296 [Addr|_] -> Addr
c31194d @yamt use sudo only when necessary
yamt authored
297 end,
2a30b69 @msantos Figure out how to run procket setuid helper
authored
298 Args = Rest ++ [IP],
299 Progname ++ " " ++
5407f2b @msantos Re-add support for binding to a specific IP
authored
300 string:join([ get_switch(Arg) || Arg <- Args ], " ") ++
6b0ebc8 @msantos sh printf is portable
authored
301 " > /dev/null 2>&1; printf $?".
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
302
6a0b92f @msantos Socket args can be either atoms or integers
authored
303 get_switch({pipe, Arg}) ->
721f6a5 @msantos Support IPv6 sockets
authored
304 "-u " ++ Arg;
96f8a1e @msantos Allow arbitrary socket family, type and protocol
authored
305
6a0b92f @msantos Socket args can be either atoms or integers
authored
306 get_switch({protocol, Proto}) when is_atom(Proto) ->
307 get_switch({protocol, protocol(Proto)});
308 get_switch({protocol, Proto}) when is_integer(Proto) ->
309 "-P " ++ integer_to_list(Proto);
96f8a1e @msantos Allow arbitrary socket family, type and protocol
authored
310
6a0b92f @msantos Socket args can be either atoms or integers
authored
311 get_switch({type, Type}) when is_atom(Type) ->
312 get_switch({type, type(Type)});
313 get_switch({type, Type}) when is_integer(Type) ->
314 "-T " ++ integer_to_list(Type);
96f8a1e @msantos Allow arbitrary socket family, type and protocol
authored
315
6a0b92f @msantos Socket args can be either atoms or integers
authored
316 get_switch({family, Family}) when is_atom(Family) ->
317 get_switch({family, family(Family)});
318 get_switch({family, Family}) when is_integer(Family) ->
319 "-F " ++ integer_to_list(Family);
96f8a1e @msantos Allow arbitrary socket family, type and protocol
authored
320
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
321 get_switch({ip, Arg}) when is_tuple(Arg) -> inet_parse:ntoa(Arg);
eba4ec3 Added option to bind a socket to a specific interface
klaar authored
322 get_switch({ip, Arg}) when is_list(Arg) -> Arg;
323
721f6a5 @msantos Support IPv6 sockets
authored
324 get_switch({port, Port}) when is_integer(Port) ->
325 "-p " ++ integer_to_list(Port);
326
315b8cf Add interface name sanitation
klaar authored
327 get_switch({interface, Name}) when is_list(Name) ->
58210fa @msantos Compile errors
authored
328 case is_interface(Name) of
bd91116 @msantos Allow setuid open of any character device
authored
329 true ->
330 "-I " ++ Name;
331 false ->
332 throw({bad_interface, Name})
333 end;
fa1f8e4 @msantos Simplify option handling
authored
334
bd91116 @msantos Allow setuid open of any character device
authored
335 get_switch({dev, Dev}) when is_list(Dev) ->
336 case is_device(Dev) of
337 true ->
338 "-d " ++ Dev;
339 false ->
340 throw({bad_device, Dev})
341 end;
dd34004 @msantos Initial support for BPF on BSDs
authored
342
fa1f8e4 @msantos Simplify option handling
authored
343 % Ignore any other arguments
344 get_switch(_Arg) ->
345 "".
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
346
bd91116 @msantos Allow setuid open of any character device
authored
347 is_interface(Name) when is_list(Name) ->
348 % An interface name is expected to consist of a reasonable
349 % subset of all characters, use a whitelist and extend it if needed
350 Name == [C || C <- Name, (((C bor 32) >= $a) and ((C bor 32) =< $z))
351 or ((C >= $0) and (C =< $9)) or (C == $.)].
352
353 is_device(Name) when is_list(Name) ->
58210fa @msantos Compile errors
authored
354 Name == [C || C <- Name, ((C >= $a) and (C =< $z))
31e7592 @msantos Allow '/' in character device name
authored
355 or ((C >= $0) and (C =< $9) or (C == $/))].
bd91116 @msantos Allow setuid open of any character device
authored
356
be946a5 @RGafiyatullin Works both when packed to ez and when used raw.
RGafiyatullin authored
357 progname_ebin() ->
358 filename:join([
359 filename:dirname( code:which( ?MODULE ) ),
360 "..", "priv", ?MODULE
361 ]).
362
363 progname_priv() ->
af8b361 @RGafiyatullin progname got from app-setting:port_executable. If no such setting is …
RGafiyatullin authored
364 case application:get_env( ?MODULE, port_executable ) of
365 {ok, Executable} -> Executable;
366 undefined -> filename:join([
367 code:priv_dir( ?MODULE ),
368 ?MODULE
369 ])
370 end.
441fde8 @msantos Interface for requesting privileged sockets in Erlang.
authored
371
be946a5 @RGafiyatullin Works both when packed to ez and when used raw.
RGafiyatullin authored
372 progname() ->
373 % Is there a proper way of getting App-Name in this context?
374 case code:priv_dir( ?MODULE ) of
2a30b69 @msantos Figure out how to run procket setuid helper
authored
375 {error, bad_name} -> progname_ebin();
376 _ -> progname_priv()
be946a5 @RGafiyatullin Works both when packed to ez and when used raw.
RGafiyatullin authored
377 end.
378
6a0b92f @msantos Socket args can be either atoms or integers
authored
379 %% Protocol family (aka domain)
380 family(unspec) -> 0;
381 family(inet) -> 2;
b6af970 @msantos portability: assign value for inet6 based on OS
authored
382 family(inet6) ->
383 case os:type() of
384 {unix, linux} -> 10;
385 {unix, darwin} -> 30;
386 {unix, freebsd} -> 28
387 end;
9b0336d @msantos Add the netlink family
authored
388 family(netlink) -> 16;
6a0b92f @msantos Socket args can be either atoms or integers
authored
389 family(packet) -> 17;
390 family(Proto) when Proto == local; Proto == unix; Proto == file -> 1;
391
392 family(0) -> unspec;
393 family(1) -> unix;
394 family(2) -> inet;
b6af970 @msantos portability: assign value for inet6 based on OS
authored
395 family(10) ->
396 case os:type() of
397 {unix, linux} -> inet6;
398 {unix, _} -> ccitt
399 end;
9b0336d @msantos Add the netlink family
authored
400 family(16) -> netlink;
b6af970 @msantos portability: assign value for inet6 based on OS
authored
401 family(17) ->
402 case os:type() of
403 {unix, linux} -> packet;
404 {unix, _} -> route
405 end;
406 family(28) ->
407 case os:type() of
408 % linux: not defined
409 {unix, freebsd} -> inet6;
410 {unix, darwin} -> isdn
411 end;
412 family(30) ->
413 case os:type() of
414 {unix, linux} -> tipc;
415 {unix, freebsd} -> atm;
416 {unix, darwin} -> inet6
417 end.
6a0b92f @msantos Socket args can be either atoms or integers
authored
418
419
420 %% Socket type
421 type(stream) -> 1;
422 type(dgram) -> 2;
423 type(raw) -> 3;
424
425 type(1) -> stream;
426 type(2) -> dgram;
427 type(3) -> raw.
428
429
430 % Select a protocol within the family (0 means use the default
431 % protocol in the family)
1a47c1d @msantos Correct value for IPPROTO_RAW
authored
432 protocol(ip) -> 0;
6a0b92f @msantos Socket args can be either atoms or integers
authored
433 protocol(icmp) -> 1;
434 protocol(tcp) -> 6;
435 protocol(udp) -> 17;
6c04231 @jj1bdx changed src/procket.erl and added ICMPv6 protocol number 58
jj1bdx authored
436 protocol(icmp6) -> 58;
f9bba43 @msantos Match the IANA protocol naming for ICMP6
authored
437 protocol('ipv6-icmp') -> 58;
1a47c1d @msantos Correct value for IPPROTO_RAW
authored
438 protocol(raw) -> 255;
6a0b92f @msantos Socket args can be either atoms or integers
authored
439
1a47c1d @msantos Correct value for IPPROTO_RAW
authored
440 protocol(0) -> ip;
6a0b92f @msantos Socket args can be either atoms or integers
authored
441 protocol(1) -> icmp;
442 protocol(6) -> tcp;
6c04231 @jj1bdx changed src/procket.erl and added ICMPv6 protocol number 58
jj1bdx authored
443 protocol(17) -> udp;
f9bba43 @msantos Match the IANA protocol naming for ICMP6
authored
444 protocol(58) -> 'ipv6-icmp';
1a47c1d @msantos Correct value for IPPROTO_RAW
authored
445 protocol(255) -> raw.
6a0b92f @msantos Socket args can be either atoms or integers
authored
446
d0508b2 @msantos Convert socket parameters to integers
authored
447 maybe_atom(_Type, Value) when is_integer(Value) -> Value;
448 maybe_atom(family, Value) -> family(Value);
449 maybe_atom(type, Value) -> type(Value);
450 maybe_atom(protocol, Value) -> protocol(Value).
451
6a0b92f @msantos Socket args can be either atoms or integers
authored
452
6dcac8f @msantos Fix sockaddr on BSD
authored
453 %%
454 %% Portability
455 %%
456
457 % struct sockaddr
458 sockaddr_common(Family, Length) ->
459 case erlang:system_info(os_type) of
460 {unix,BSD} when BSD == darwin;
461 BSD == openbsd;
462 BSD == netbsd;
463 BSD == freebsd ->
464 <<Length:8, Family:8>>;
465 {unix,_} ->
466 <<Family:16/native>>
467 end.
468
469 % UNIX_PATH_MAX
470 unix_path_max() ->
471 case erlang:system_info(os_type) of
472 {unix,BSD} when BSD == darwin;
473 BSD == openbsd;
474 BSD == netbsd;
475 BSD == freebsd -> 104;
476 {unix,_} -> 108
477 end.
478
dd34004 @msantos Initial support for BPF on BSDs
authored
479
480 ntohl(<<I:32>>) ->
481 ntohl(I);
482 ntohl(I) when is_integer(I) ->
483 <<N:32>> = <<I:32/native>>,
484 N.
485 ntohs(<<I:32>>) ->
486 ntohs(I);
487 ntohs(I) when is_integer(I) ->
488 <<N:16>> = <<I:16/native>>,
489 N.
06dfd93 @msantos Align structure used for LSF on a word
authored
490
491
492 wordalign(Offset) ->
493 wordalign(Offset, erlang:system_info({wordsize, external})).
494 wordalign(Offset, Align) ->
495 (Align - (Offset rem Align)) rem Align.
Something went wrong with that request. Please try again.