1 ! Copyright (C) 2007 Doug Coleman, Slava Pestov
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays byte-arrays io.backend io.binary io.sockets
4 kernel math math.parser sequences splitting system
5 alien.c-types combinators namespaces alien ;
8 USE-IF: windows? windows.winsock
11 GENERIC: protocol-family ( addrspec -- af )
13 GENERIC: sockaddr-type ( addrspec -- type )
15 GENERIC: make-sockaddr ( addrspec -- sockaddr type )
17 GENERIC: parse-sockaddr ( sockaddr addrspec -- newaddrspec )
19 HOOK: addrinfo-error io-backend ( n -- )
22 GENERIC: address-size ( addrspec -- n )
24 GENERIC: inet-ntop ( data addrspec -- str )
26 GENERIC: inet-pton ( str addrspec -- data )
29 M: inet4 inet-ntop ( data addrspec -- str )
30 drop 4 memory>string [ number>string ] { } map-as "." join ;
32 M: inet4 inet-pton ( str addrspec -- data )
33 drop "." split [ string>number ] B{ } map-as ;
35 M: inet4 address-size drop 4 ;
37 M: inet4 protocol-family drop PF_INET ;
39 M: inet4 sockaddr-type drop "sockaddr-in" ;
41 M: inet4 make-sockaddr ( inet -- sockaddr type )
42 "sockaddr-in" <c-object>
43 AF_INET over set-sockaddr-in-family
44 over inet4-port htons over set-sockaddr-in-port
47 rot inet-pton *uint over set-sockaddr-in-addr
50 M: inet4 parse-sockaddr
51 >r dup sockaddr-in-addr <uint> r> inet-ntop
52 swap sockaddr-in-port ntohs <inet4> ;
55 M: inet6 inet-ntop ( data addrspec -- str )
56 drop 16 memory>string 2 <groups> [ be> >hex ] map ":" join ;
58 M: inet6 inet-pton ( str addrspec -- data )
60 [ [ ":" split [ hex> dup 0 ? ] map ] [ f ] if* ] 2apply
61 2dup [ length ] 2apply + 8 swap - 0 <array> swap 3append
62 [ 2 >be ] map concat >byte-array ;
64 M: inet6 address-size drop 16 ;
66 M: inet6 protocol-family drop PF_INET6 ;
68 M: inet6 sockaddr-type drop "sockaddr-in6" ;
70 M: inet6 make-sockaddr ( inet -- sockaddr type )
71 "sockaddr-in6" <c-object>
72 AF_INET6 over set-sockaddr-in6-family
73 over inet6-port htons over set-sockaddr-in6-port
74 over inet6-host "::" or
75 rot inet-pton over set-sockaddr-in6-addr
78 M: inet6 parse-sockaddr
79 >r dup sockaddr-in6-addr r> inet-ntop
80 swap sockaddr-in6-port ntohs <inet6> ;
82 : addrspec-of-family ( af -- addrspec )
84 { [ dup AF_INET = ] [ T{ inet4 } ] }
85 { [ dup AF_INET6 = ] [ T{ inet6 } ] }
86 { [ dup AF_UNIX = ] [ T{ local } ] }
90 M: f parse-sockaddr nip ;
92 : addrinfo>addrspec ( addrinfo -- addrspec )
94 swap addrinfo-family addrspec-of-family
97 : addrspec, ( addrinfo -- )
98 [ dup addrinfo>addrspec , addrinfo-next addrspec, ] when* ;
100 : parse-addrinfo-list ( addrinfo -- seq )
101 [ addrspec, ] { } make [ ] subset ;
103 M: object resolve-host ( host serv passive? -- seq )
104 >r dup integer? [ number>string ] when
105 "addrinfo" <c-object>
106 r> [ AI_PASSIVE over set-addrinfo-flags ] when
107 PF_UNSPEC over set-addrinfo-family
108 IPPROTO_TCP over set-addrinfo-protocol
109 f <void*> [ getaddrinfo addrinfo-error ] keep *void*
110 [ parse-addrinfo-list ] keep
113 M: object host-name ( -- name )
114 256 <byte-array> dup dup length gethostname
115 zero? [ "gethostname failed" throw ] unless
118 : >mac-address ( byte-array -- string )
119 6 memory>string >byte-array
120 [ >hex 2 48 pad-left ] { } map-as ":" join ;