libstddjb
libskarnet
skalibs
Software
skarnet.org

# The `ip46` library interface

The following functions and structures are declared in the `skalibs/ip46.h` header, and implemented in the `libskarnet.a` or `libskarnet.so` library.

## General information

`ip46` is a set of macros and functions to support both IPv4 and IPv6 network operations in an abstracted way.

If skalibs has been built with the --disable-ipv6 configure option, or it detects at build time than the target does not support IPv6, then `ip46` structures and functions will be directly aliased to their IPv4 implementations with no overhead at all.

## Data structures

An `ip46full_t` is a structure that contains either an IPv4 or an IPv6 address. If a is an `ip46full_t`, then:

- ip46_is6(&a) is 1 if a is IPv6 and 0 otherwise.
- a.ip points to 16 (if IPv6) or 4 (if IPv4) bytes containing the address, in network byte order.

If skalibs has been build with IPv6 support, an `ip46_t` is the same type as an `ip46full_t`. Otherwise, an `ip46_t` is a structure that just contains an IPv4 address.

## Functions

`int ip46_from_ip4 (ip46_t *a, char const *ip)`
Stores the IPv4 pointed to by ip into *a. Returns 1.

`int ip46_from_ip6 (ip46_t *a, char const *ip)`
Stores the IPv6 pointed to by ip into *a. Returns 1, except if IPv6 is unavailable, in which case it returns 0 ENOSYS.

`size_t ip46_fmt (char *s, ip46_t const *a)`
Formats the address in *a into the string s, which must be preallocated. Returns the number of bytes written. The address will be accordingly formatted as IPv4 or IPv6.

`size_t ip46_scan (char const *s, ip46_t *a)`
Scans the string s for an IPv4 or IPv6 address. If it finds one, writes it into *a and returns the number of bytes read. If it cannot, returns 0.

`size_t ip46_scanlist (ip46_t *list, size_t max, char const *s, size_t *n)`
Scans the string s for a list of comma-, semicolon-, space-, tab- or newline-separated IPv4 or IPv6 addresses, up to a maximum of max. It stores them into the (preallocated) ip46_t array pointed to by list. It returns the number of bytes read (0 if s does not contain a valid IP list at all), and stores the number of found and scanned addresses into *n.

`int socket_connect46 (int fd, ip46_t *a, uint16_t port)`
Connects the socket fd to address *a and port port. Returns 0 in case of success, and -1 (and sets errno) in case of failure.

`int socket_bind46 (int fd, ip46_t *a, uint16_t port)`
Binds the socket fd to address *a and port port. Returns 0 in case of success, and -1 (and sets errno) in case of failure.

`int socket_bind46_reuse (int fd, ip46_t *a, uint16_t port)`
Same as the previous function, with the SO_REUSEADDR option.

`int socket_deadlineconnstamp46 (int fd, ip46_t const *a, uint16_t port, tain const *deadline, tain *stamp)`
Attempts to synchronously connect the socket fd to address aa and port port. Returns 1 if it succeeds and 0 (and sets errno) if it fails. stamp must contain an accurate enough timestamp, and is updated when the function returns. If the connection is still pending by deadline, then the attempt stops and the function returns 0 ETIMEDOUT.

`ssize_t socket_recv46 (int fd, char *s, size_t len, ip46_t *a, uint16_t *port)`
Reads a datagram from socket fd. The message is stored into buffer s of max length len, and stores the sender information into address *a and port *port. Returns the length of the read datagram, or -1 if it fails.

`ssize_t socket_send46 (int fd, char const *s, size_t len, ip46_t const *a, uint16_t port)`
Writes a datagram to socket fd. The message is read from buffer s of length len, and the recipient information is address *a and port port. Returns the number of written bytes, or -1 if it fails.

`int socket_local46 (int fd, ip46_t *a, uint16_t *port)`
Gets the local information about bound socket fd: the local IP address is stored into *a and the local port into *port. Returns 0 in case of success, and -1 (and sets errno) in case of failure.

`int socket_remote46 (int fd, ip46_t *a, uint16_t *port)`
Gets the peer information about connected socket fd: the remote IP address is stored into *a and the remote port into *port. Returns 0 in case of success, and -1 (and sets errno) in case of failure.

`ssize_t socket_recvnb46 (int fd, char *s, size_t len, ip46_t *a, uint16_t *port, tain const *deadline, tain *stamp)`
Like `socket_recv46`, except that the function blocks until a datagram is received. *stamp must be an accurate enough approximation of the current time, and is updated when the function returns. If no datagram has arrived by absolute date *deadline, the function returns -1 ETIMEOUT.

`ssize_t socket_sendnb46 (int fd, char const *s, size_t len, ip46_t const *a, uint16_t port, tain const *deadline, tain *stamp)`
Like `socket_send46`, except that the function blocks until a datagram has been effectively sent. *stamp must be an accurate enough approximation of the current time, and is updated when the function returns. If the message still has not been sent by absolute date *deadline, the function returns -1 ETIMEOUT.