… | |
… | |
57 | inet_aton |
57 | inet_aton |
58 | tcp_server |
58 | tcp_server |
59 | tcp_connect |
59 | tcp_connect |
60 | ); |
60 | ); |
61 | |
61 | |
62 | our $VERSION = 4.42; |
62 | our $VERSION = 4.452; |
63 | |
63 | |
64 | =item $ipn = parse_ipv4 $dotted_quad |
64 | =item $ipn = parse_ipv4 $dotted_quad |
65 | |
65 | |
66 | Tries to parse the given dotted quad IPv4 address and return it in |
66 | Tries to parse the given dotted quad IPv4 address and return it in |
67 | octet form (or undef when it isn't in a parsable format). Supports all |
67 | octet form (or undef when it isn't in a parsable format). Supports all |
… | |
… | |
144 | ? pack "S", AF_UNIX |
144 | ? pack "S", AF_UNIX |
145 | : undef |
145 | : undef |
146 | |
146 | |
147 | } |
147 | } |
148 | |
148 | |
149 | =item $ipn = parse_address $text |
149 | =item $ipn = parse_address $ip |
150 | |
150 | |
151 | Combines C<parse_ipv4> and C<parse_ipv6> in one function. The address |
151 | Combines C<parse_ipv4> and C<parse_ipv6> in one function. The address |
152 | here refers to the host address (not socket address) in network form |
152 | here refers to the host address (not socket address) in network form |
153 | (binary). |
153 | (binary). |
154 | |
154 | |
155 | If the C<$text> is C<unix/>, then this function returns a special token |
155 | If the C<$text> is C<unix/>, then this function returns a special token |
156 | recognised by the other functions in this module to mean "UNIX domain |
156 | recognised by the other functions in this module to mean "UNIX domain |
157 | socket". |
157 | socket". |
158 | |
158 | |
|
|
159 | If the C<$text> to parse is a mapped IPv4 in IPv6 address (:ffff::<ipv4>), |
|
|
160 | then it will be treated as an IPv4 address. If you don't want that, you |
|
|
161 | have to call C<parse_ipv4> and/or C<parse_ipv6> manually. |
|
|
162 | |
159 | =item $text = AnyEvent::Socket::aton $ipn |
163 | =item $ipn = AnyEvent::Socket::aton $ip |
160 | |
164 | |
161 | Same as C<parse_address>, but not exported (think C<Socket::inet_aton> but |
165 | Same as C<parse_address>, but not exported (think C<Socket::inet_aton> but |
162 | I<without> name resolution). |
166 | I<without> name resolution). |
163 | |
167 | |
164 | =cut |
168 | =cut |
165 | |
169 | |
166 | sub parse_address($) { |
170 | sub parse_address($) { |
167 | &parse_ipv4 || &parse_ipv6 || &parse_unix |
171 | for (&parse_ipv6) { |
|
|
172 | if ($_) { |
|
|
173 | s/^\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff//; |
|
|
174 | return $_; |
|
|
175 | } else { |
|
|
176 | return &parse_ipv4 || &parse_unix |
|
|
177 | } |
|
|
178 | } |
168 | } |
179 | } |
169 | |
180 | |
170 | *aton = \&parse_address; |
181 | *aton = \&parse_address; |
171 | |
182 | |
172 | =item ($host, $service) = parse_hostport $string[, $default_service] |
183 | =item ($host, $service) = parse_hostport $string[, $default_service] |
… | |
… | |
259 | : 16 == length $_[0] |
270 | : 16 == length $_[0] |
260 | ? AF_INET6 |
271 | ? AF_INET6 |
261 | : unpack "S", $_[0] |
272 | : unpack "S", $_[0] |
262 | } |
273 | } |
263 | |
274 | |
|
|
275 | =item $text = format_ipv4 $ipn |
|
|
276 | |
|
|
277 | Expects a four octet string representing a binary IPv4 address and returns |
|
|
278 | its textual format. Rarely used, see C<format_address> for a nicer |
|
|
279 | interface. |
|
|
280 | |
|
|
281 | =item $text = format_ipv6 $ipn |
|
|
282 | |
|
|
283 | Expects a sixteen octet string representing a binary IPv6 address and |
|
|
284 | returns its textual format. Rarely used, see C<format_address> for a |
|
|
285 | nicer interface. |
|
|
286 | |
264 | =item $text = format_address $ipn |
287 | =item $text = format_address $ipn |
265 | |
288 | |
266 | Covnvert a host address in network format (e.g. 4 octets for IPv4 or 16 |
289 | Covnvert a host address in network format (e.g. 4 octets for IPv4 or 16 |
267 | octets for IPv6) and convert it into textual form. |
290 | octets for IPv6) and convert it into textual form. |
268 | |
291 | |
… | |
… | |
271 | This function works similarly to C<inet_ntop AF_INET || AF_INET6, ...>, |
294 | This function works similarly to C<inet_ntop AF_INET || AF_INET6, ...>, |
272 | except it automatically detects the address type. |
295 | except it automatically detects the address type. |
273 | |
296 | |
274 | Returns C<undef> if it cannot detect the type. |
297 | Returns C<undef> if it cannot detect the type. |
275 | |
298 | |
|
|
299 | If the C<$ipn> is a mapped IPv4 in IPv6 address (:ffff::<ipv4>), then just |
|
|
300 | the contained IPv4 address will be returned. If you do not want that, you |
|
|
301 | have to call C<format_ipv6> manually. |
|
|
302 | |
276 | =item $text = AnyEvent::Socket::ntoa $ipn |
303 | =item $text = AnyEvent::Socket::ntoa $ipn |
277 | |
304 | |
278 | Same as format_address, but not exported (think C<inet_ntoa>). |
305 | Same as format_address, but not exported (think C<inet_ntoa>). |
279 | |
306 | |
280 | =cut |
307 | =cut |
281 | |
308 | |
282 | sub format_address; |
309 | sub format_ipv4($) { |
|
|
310 | join ".", unpack "C4", $_[0] |
|
|
311 | } |
|
|
312 | |
|
|
313 | sub format_ipv6($) { |
|
|
314 | if (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 eq $_[0]) { |
|
|
315 | return "::"; |
|
|
316 | } elsif (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1 eq $_[0]) { |
|
|
317 | return "::1"; |
|
|
318 | } elsif (v0.0.0.0.0.0.0.0.0.0.0.0 eq substr $_[0], 0, 12) { |
|
|
319 | # v4compatible |
|
|
320 | return "::" . format_ipv4 substr $_[0], 12; |
|
|
321 | } elsif (v0.0.0.0.0.0.0.0.0.0.255.255 eq substr $_[0], 0, 12) { |
|
|
322 | # v4mapped |
|
|
323 | return "::ffff:" . format_ipv4 substr $_[0], 12; |
|
|
324 | } elsif (v0.0.0.0.0.0.0.0.255.255.0.0 eq substr $_[0], 0, 12) { |
|
|
325 | # v4translated |
|
|
326 | return "::ffff:0:" . format_ipv4 substr $_[0], 12; |
|
|
327 | } else { |
|
|
328 | my $ip = sprintf "%x:%x:%x:%x:%x:%x:%x:%x", unpack "n8", $_[0]; |
|
|
329 | |
|
|
330 | # this is rather sucky, I admit |
|
|
331 | $ip =~ s/^0:(?:0:)*(0$)?/::/ |
|
|
332 | or $ip =~ s/(:0){7}$/::/ or $ip =~ s/(:0){7}/:/ |
|
|
333 | or $ip =~ s/(:0){6}$/::/ or $ip =~ s/(:0){6}/:/ |
|
|
334 | or $ip =~ s/(:0){5}$/::/ or $ip =~ s/(:0){5}/:/ |
|
|
335 | or $ip =~ s/(:0){4}$/::/ or $ip =~ s/(:0){4}/:/ |
|
|
336 | or $ip =~ s/(:0){3}$/::/ or $ip =~ s/(:0){3}/:/ |
|
|
337 | or $ip =~ s/(:0){2}$/::/ or $ip =~ s/(:0){2}/:/ |
|
|
338 | or $ip =~ s/(:0){1}$/::/ or $ip =~ s/(:0){1}/:/; |
|
|
339 | return $ip |
|
|
340 | } |
|
|
341 | } |
|
|
342 | |
283 | sub format_address($) { |
343 | sub format_address($) { |
284 | my $af = address_family $_[0]; |
344 | my $af = address_family $_[0]; |
285 | if ($af == AF_INET) { |
345 | if ($af == AF_INET) { |
286 | return join ".", unpack "C4", $_[0] |
346 | return &format_ipv4; |
287 | } elsif ($af == AF_INET6) { |
347 | } elsif ($af == AF_INET6) { |
288 | if (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 eq $_[0]) { |
|
|
289 | return "::"; |
|
|
290 | } elsif (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1 eq $_[0]) { |
|
|
291 | return "::1"; |
|
|
292 | } elsif (v0.0.0.0.0.0.0.0.0.0.0.0 eq substr $_[0], 0, 12) { |
|
|
293 | # v4compatible |
|
|
294 | return "::" . format_address substr $_[0], 12; |
|
|
295 | } elsif (v0.0.0.0.0.0.0.0.0.0.255.255 eq substr $_[0], 0, 12) { |
348 | return (v0.0.0.0.0.0.0.0.0.0.255.255 eq substr $_[0], 0, 12) |
296 | # v4mapped |
349 | ? format_ipv4 substr $_[0], 12 |
297 | return "::ffff:" . format_address substr $_[0], 12; |
350 | : &format_ipv6; |
298 | } elsif (v0.0.0.0.0.0.0.0.255.255.0.0 eq substr $_[0], 0, 12) { |
|
|
299 | # v4translated |
|
|
300 | return "::ffff:0:" . format_address substr $_[0], 12; |
|
|
301 | } else { |
|
|
302 | my $ip = sprintf "%x:%x:%x:%x:%x:%x:%x:%x", unpack "n8", $_[0]; |
|
|
303 | |
|
|
304 | # this is rather sucky, I admit |
|
|
305 | $ip =~ s/^0:(?:0:)*(0$)?/::/ |
|
|
306 | or $ip =~ s/(:0){7}$/::/ or $ip =~ s/(:0){7}/:/ |
|
|
307 | or $ip =~ s/(:0){6}$/::/ or $ip =~ s/(:0){6}/:/ |
|
|
308 | or $ip =~ s/(:0){5}$/::/ or $ip =~ s/(:0){5}/:/ |
|
|
309 | or $ip =~ s/(:0){4}$/::/ or $ip =~ s/(:0){4}/:/ |
|
|
310 | or $ip =~ s/(:0){3}$/::/ or $ip =~ s/(:0){3}/:/ |
|
|
311 | or $ip =~ s/(:0){2}$/::/ or $ip =~ s/(:0){2}/:/ |
|
|
312 | or $ip =~ s/(:0){1}$/::/ or $ip =~ s/(:0){1}/:/; |
|
|
313 | return $ip |
|
|
314 | } |
|
|
315 | } elsif ($af == AF_UNIX) { |
351 | } elsif ($af == AF_UNIX) { |
316 | return "unix/" |
352 | return "unix/" |
317 | } else { |
353 | } else { |
318 | return undef |
354 | return undef |
319 | } |
355 | } |