Main Page Modules Data Structures File List Data Fields Globals Related Pages

# Exported Functions
[Cross-platform socket utilities (IPv4-IPv6)]

## Functions
int | sock_init (char *errbuf, int errbuflen)
| It initializes sockets.
void | sock_cleanup ()
| It deallocates sockets.
void | sock_geterror (const char *caller, char *errbuf, int errbufsize)
| It retrieves the error message after an error occurred in the socket interface.
int | sock_initaddress (const char *address, const char *port, struct addrinfo *hints, struct addrinfo **addrinfo, char *errbuf, int errbuflen)
| Checks that the address, port and flags given are valids and it returns an 'addrinfo' stucture.
int | sock_recv (SOCKET socket, char *buffer, int size, int receiveall, char *errbuf, int errbuflen)
| It waits on a connected socket and it manages to receive data.
SOCKET | sock_open (struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen)
| It initializes a network connection both from the client and the server side.
int | sock_close (SOCKET sock, char *errbuf, int errbuflen)
| Closes the present (TCP and UDP) socket connection.
int | sock_send (SOCKET socket, const char *buffer, int size, char *errbuf, int errbuflen)
| It sends the amount of data contained into 'buffer' on the given socket.
int | sock_bufferize (const char *buffer, int size, char *tempbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen)
| It copies the amount of data contained into 'buffer' into 'tempbuf'. and it checks for buffer overflows.
int | sock_discard (SOCKET socket, int size, char *errbuf, int errbuflen)
| It waits on a connected socket and it manages to receive one message. It discards N bytes that are currently waiting to be read on the current socket.
int | sock_check_hostlist (char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen)
| Checks that one host (identified by the sockaddr_storage structure) belongs to an 'allowed list'.
int | sock_cmpaddr (struct sockaddr_storage *first, struct sockaddr_storage *second)
| Compares two addresses contained into two sockaddr_storage structures.
int | sock_getascii_addrport (const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen)
| It retrieves two strings containing the address and the port of a given 'sockaddr' variable.
int | sock_present2network (const char *address, struct sockaddr_storage *sockaddr, char *errbuf, int errbuflen)
| It translates an address from the 'presentation' form into the 'network' form.

## Function Documentation

int sock_bufferize | ( | const char * | buffer,
|  | int | size,
|  | char * | tempbuf,
|  | int * | offset,
|  | int | totsize,
|  | int | checkonly,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | It copies the amount of data contained into 'buffer' into 'tempbuf'. and it checks for buffer overflows. This function basically copies 'size' bytes of data contained into 'buffer' into 'tempbuf', starting at offset 'offset'. Before that, it checks that the resulting buffer will not be larger than 'totsize'. Finally, it updates the 'offset' variable in order to point to the first empty location of the buffer. In case the function is called with 'checkonly' equal to 1, it does not copy the data into the buffer. It only checks for buffer overflows and it updates the 'offset' variable. This mode can be useful when the buffer already contains the data (maybe because the producer writes directly into the target buffer), so only the buffer overflow check has to be made. In this case, both 'buffer' and 'tempbuf' can be NULL values. This function is useful in case the userland application does not know immediately all the data it has to write into the socket. This function provides a way to create the "stream" step by step, appendning the new data to the old one. Then, when all the data has been bufferized, the application can call the sock_send() function. Parameters:
  buffer: | a char pointer to a user-allocated buffer that keeps the data that has to be copied.
  size: | number of bytes that have to be copied.
  tempbuf: | user-allocated buffer (of size 'totsize') in which data has to be copied.
  offset: | an index into 'tempbuf' which keeps the location of its first empty location.
  totsize: | total size of the buffer in which data is being copied.
  checkonly: | '1' if we do not want to copy data into the buffer and we want just do a buffer ovreflow control, '0' if data has to be copied as well.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: '0' if everything is fine, '-1' if some errors occurred. The error message is returned in the 'errbuf' variable. When the function returns, 'tempbuf' will have the new string appended, and 'offset' will keep the length of that buffer. In case of 'checkonly == 1', data is not copied, but 'offset' is updated in any case. Warning: This function assumes that the buffer in which data has to be stored is large 'totbuf' bytes. In case of 'checkonly', be carefully to call this function *before* copying the data into the buffer. Otherwise, the control about the buffer overflow is useless. Definition at line 625 of file sockutils.c. References errbuf, offset, size, and snprintf. Referenced by daemon_findalldevs(), daemon_getstats(), daemon_getstatsnopcap(), daemon_opensource(), daemon_startcapture(), daemon_thrdatamain(), pcap_opensource_remote(), pcap_pack_bpffilter(), pcap_setsampling_remote(), pcap_startcapture_remote(), pcap_updatefilter_remote(), rpcap_sendauth(), and rpcap_senderror().

int sock_check_hostlist | ( | char * | hostlist,
|  | const char * | sep,
|  | struct sockaddr_storage * | from,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | Checks that one host (identified by the sockaddr_storage structure) belongs to an 'allowed list'. This function is useful after an accept() call in order to check if the connecting host is allowed to connect to me. To do that, we have a buffer that keeps the list of the allowed host; this function checks the sockaddr_storage structure of the connecting host against this host list, and it returns '0' is the host is included in this list. Parameters:
  hostlist: | pointer to a string that contains the list of the allowed host.
  sep: | a string that keeps the separators used between the hosts (for example the space character) in the host list.
  from: | a sockaddr_storage structure, as it is returned by the accept() call.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: It returns: '1' if the host list is empty '0' if the host belongs to the host list (and therefore it is allowed to connect) '-1' in case the host does not belong to the host list (and therefore it is not allowed to connect '-2' in case or error. The error message is returned in the 'errbuf' variable. Definition at line 883 of file sockutils.c. References errbuf, hostlist, snprintf, SOCK_ASSERT, sock_cmpaddr(), and sock_geterror(). Referenced by main_passive(), and pcap_remoteact_accept().

void sock_cleanup | ( |  | ) |

| It deallocates sockets. This function is pretty useless on UNIX, since socket deallocation is not required. However it is required on Win32. In UNIX, this function appears to be completely empty. Returns: No error values. Definition at line 225 of file sockutils.c. References sockcount. Referenced by main_cleanup(), pcap_close_remote(), pcap_findalldevs_ex(), pcap_remoteact_cleanup(), and pcap_remoteact_close().

int sock_close | ( | SOCKET | sock,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | Closes the present (TCP and UDP) socket connection. This function sends a shutdown() on the socket in order to disable send() calls (while recv() ones are still allowed). Then, it closes the socket. Parameters:
  sock: | the socket identifier of the connection that has to be closed.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: '0' if everything is fine, '-1' if some errors occurred. The error message is returned in the 'errbuf' variable. Definition at line 396 of file sockutils.c. References sock_geterror(). Referenced by daemon_endcapture(), daemon_serviceloop(), daemon_startcapture(), main_passive(), pcap_close_remote(), pcap_findalldevs_ex(), pcap_opensource_remote(), pcap_remoteact_accept(), pcap_remoteact_close(), and pcap_startcapture_remote().

int sock_cmpaddr | ( | struct sockaddr_storage * | first,
|  | struct sockaddr_storage * | second
| ) |

  | Compares two addresses contained into two sockaddr_storage structures. This function is useful to compare two addresses, given their internal representation, i.e. an sockaddr_storage structure. The two structures do not need to be sockaddr_storage; you can have both 'sockaddr_in' and sockaddr_in6, properly acsted in order to be compliant to the function interface. This function will return '0' if the two addresses matches, '-1' if not. Parameters:
  first: | a sockaddr_storage structure, (for example the one that is returned by an accept() call), containing the first address to compare.
  second: | a sockaddr_storage structure containing the second address to compare.
Returns: '0' if the addresses are equal, '-1' if they are different. Definition at line 992 of file sockutils.c. Referenced by pcap_remoteact_accept(), pcap_remoteact_close(), rpcap_remoteact_getsock(), and sock_check_hostlist().

int sock_discard | ( | SOCKET | sock,
|  | int | size,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | It waits on a connected socket and it manages to receive one message. It discards N bytes that are currently waiting to be read on the current socket. This function is useful in case we receive a message we cannot undestand (e.g. wrong version number when receiving a network packet), so that we have to discard all data before reading a new message. This function will read 'size' bytes from the socket and discard them. It defines an internal buffer in which data will be copied; however, in case this buffer is not large enough, it will cycle in order to read everything as well. Parameters:
  sock: | the connected socket currently opened.
  size: | number of bytes that have to be discarded.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: '0' if everything is fine, '-1' if some errors occurred. The error message is returned in the 'errbuf' variable. Definition at line 821 of file sockutils.c. References size, SOCK_ASSERT, and sock_recv(). Referenced by daemon_checkauth(), daemon_opensource(), daemon_serviceloop(), daemon_setsampling(), daemon_startcapture(), daemon_updatefilter(), pcap_close_remote(), pcap_findalldevs_ex(), pcap_opensource_remote(), pcap_read_nocb_remote(), pcap_setsampling_remote(), pcap_startcapture_remote(), pcap_updatefilter_remote(), rpcap_checkmsg(), rpcap_checkver(), rpcap_sendauth(), and rpcap_stats_remote().

int sock_getascii_addrport | ( | const struct sockaddr_storage * | sockaddr,
|  | char * | address,
|  | int | addrlen,
|  | char * | port,
|  | int | portlen,
|  | int | flags,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | It retrieves two strings containing the address and the port of a given 'sockaddr' variable. This function is basically an extended version of the inet_ntop(), which does not exist in WIN32 because the same result can be obtained by using the getnameinfo(). However, differently from inet_ntop(), this function is able to return also literal names (e.g. 'locahost') dependingly from the 'Flags' parameter. The function accepts a sockaddr_storage variable (which can be returned by several functions like bind(), connect(), accept(), and more) and it transforms its content into a 'human' form. So, for instance, it is able to translate an hex address (stored in bynary form) into a standard IPv6 address like "::1". The behaviour of this function depends on the parameters we have in the 'Flags' variable, which are the ones allowed in the standard getnameinfo() socket function. Parameters:
  sockaddr: | a 'sockaddr_in' or 'sockaddr_in6' structure containing the address that need to be translated from network form into the presentation form. This structure must be zero-ed prior using it, and the address family field must be filled with the proper value. The user must cast any 'sockaddr_in' or 'sockaddr_in6' structures to 'sockaddr_storage' before calling this function.
  address: | it contains the address that will be returned by the function. This buffer must be properly allocated by the user. The address can be either literal or numeric depending on the value of 'Flags'.
  addrlen: | the length of the 'Addr' buffer.
  port: | it contains the port that will be returned by the function. This buffer must be properly allocated by the user.
  portlen: | the length of the 'Port' buffer.
  flags: | a set of flags (the ones defined into the getnameinfo() standard socket function) that determine if the resulting address must be in numeric / literal form, and so on.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: It returns '-1' if this function succeedes, '0' otherwise. The address and port corresponding to the given SockAddr is returned back in the buffers 'Addr' and 'Port'. In any case, the returned strings are '0' terminated. Definition at line 1065 of file sockutils.c. References address, errbuf, port, and sock_geterror(). Referenced by pcap_remoteact_list().

void sock_geterror | ( | const char * | caller,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | It retrieves the error message after an error occurred in the socket interface. This function is defined because of the different way errors are returned in UNIX and Win32. This function provides a consistent way to retrieve the error message (after a socket error occurred) on all the platforms. Parameters:
  caller: | a pointer to a user-allocated string which contains a message that has to be printed *before* the true error message. It could be, for example, 'this error comes from the recv() call at line 31'.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: No return values. The error message is returned in the 'string' parameter. Definition at line 123 of file sockutils.c. References errbuf, snprintf, and SOCK_ERRBUF_SIZE. Referenced by daemon_serviceloop(), daemon_startcapture(), main_passive(), pcap_read_nocb_remote(), pcap_remoteact_accept(), pcap_startcapture_remote(), sock_check_hostlist(), sock_close(), sock_getascii_addrport(), sock_initaddress(), sock_open(), sock_recv(), and sock_send().

int sock_init | ( | char * | errbuf,
|  | int | errbuflen
| ) |

  | It initializes sockets. This function is pretty useless on UNIX, since socket initialization is not required. However it is required on Win32. In UNIX, this function appears to be completely empty. Parameters:
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: '0' if everything is fine, '-1' if some errors occurred. The error message is returned in the 'errbuf' variable. Definition at line 187 of file sockutils.c. References errbuf, snprintf, and sockcount. Referenced by main(), pcap_findalldevs_ex(), pcap_opensource_remote(), and pcap_remoteact_accept().

int sock_initaddress | ( | const char * | address,
|  | const char * | port,
|  | struct addrinfo * | hints,
|  | struct addrinfo ** | addrinfo,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | Checks that the address, port and flags given are valids and it returns an 'addrinfo' stucture. This function basically calls the getaddrinfo() calls, and it performs a set of sanity checks to control that everything is fine (e.g. a TCP socket cannot have a mcast address, and such). If an error occurs, it writes the error message into 'errbuf'. Parameters:
  address: | a pointer to a user-allocated buffer containing the network address to check. It could be both a numeric - literal address, and it can be NULL or "" (useful in case of a server socket which has to bind to all addresses).
  port: | a pointer to a user-allocated buffer containing the network port to use.
  hints: | an addrinfo variable (passed by reference) containing the flags needed to create the addrinfo structure appropriately.
  addrinfo: | it represents the true returning value. This is a pointer to an addrinfo variable (passed by reference), which will be allocated by this function and returned back to the caller. This variable will be used in the next sockets calls.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: '0' if everything is fine, '-1' if some errors occurred. The error message is returned in the 'errbuf' variable. The addrinfo variable that has to be used in the following sockets calls is returned into the addrinfo parameter. Warning: The 'addrinfo' variable has to be deleted by the programmer by calling freeaddrinfo() when it is no longer needed. This function requires the 'hints' variable as parameter. The semantic of this variable is the same of the one of the corresponding variable used into the standard getaddrinfo() socket function. We suggest the programmer to look at that function in order to set the 'hints' variable appropriately. SOCKET: I should check all the accept() in order to bind to all addresses in case addrinfo has more han one pointers Definition at line 456 of file sockutils.c. References errbuf, snprintf, sock_geterror(), and sock_ismcastaddr(). Referenced by daemon_startcapture(), main_active(), main_startup(), pcap_findalldevs_ex(), pcap_opensource_remote(), pcap_remoteact_accept(), pcap_startcapture_remote(), and sock_present2network().

SOCKET sock_open | ( | struct addrinfo * | addrinfo,
|  | int | server,
|  | int | nconn,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | It initializes a network connection both from the client and the server side. In case of a client socket, this function calls socket() and connect(). In the meanwhile, it checks for any socket error. If an error occurs, it writes the error message into 'errbuf'. In case of a server socket, the function calls socket(), bind() and listen(). This function is usually preceeded by the sock_initaddress(). Parameters:
  addrinfo: | pointer to an addrinfo variable which will be used to open the socket and such. This variable is the one returned by the previous call to sock_initaddress().
  server: | '1' if this is a server socket, '0' otherwise.
  nconn: | number of the connections that are allowed to wait into the listen() call. This value has no meanings in case of a client socket.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: the socket that has been opened (that has to be used in the following sockets calls) if everything is fine, '-1' if some errors occurred. The error message is returned in the 'errbuf' variable. Definition at line 291 of file sockutils.c. References errbuf, snprintf, sock_geterror(), and SOCKET. Referenced by daemon_startcapture(), main_active(), main_startup(), pcap_findalldevs_ex(), pcap_opensource_remote(), pcap_remoteact_accept(), and pcap_startcapture_remote().

int sock_present2network | ( | const char * | address,
|  | struct sockaddr_storage * | sockaddr,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | It translates an address from the 'presentation' form into the 'network' form. This function basically replaces inet_pton(), which does not exist in WIN32 because the same result can be obtained by using the getaddrinfo(). An addictional advantage is that 'Address' can be both a numeric address (e.g. '127.0.0.1', like in inet_pton() ) and a literal name (e.g. 'localhost'). This function does the reverse job of sock_getascii_addrport(). Parameters:
  address: | a zero-terminated string which contains the name you have to translate. The name can be either literal (e.g. 'localhost') or numeric (e.g. '::1').
  sockaddr: | a user-allocated sockaddr_storage structure which will contains the 'network' form of the requested address.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: '-1' if the translation succeded, '-2' if there was some non critical error, '0' otherwise. In case it fails, the content of the SockAddr variable remains unchanged. A 'non critical error' can occur in case the 'Address' is a literal name, which can be mapped to several network addresses (e.g. 'foo.bar.com' => '10.2.2.2' and '10.2.2.3'). In this case the content of the SockAddr parameter will be the address corresponding to the first mapping. Warning: The sockaddr_storage structure MUST be allocated by the user. Definition at line 1150 of file sockutils.c. References errbuf, snprintf, and sock_initaddress().

int sock_recv | ( | SOCKET | sock,
|  | char * | buffer,
|  | int | size,
|  | int | receiveall,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | It waits on a connected socket and it manages to receive data. This function basically calls the recv() socket function and it checks that no error occurred. If that happens, it writes the error message into 'errbuf'. This function changes its behaviour according to the 'receiveall' flag: if we want to receive exactly 'size' byte, it loops on the recv() until all the requested data is arrived. Otherwise, it returns the data currently available. In case the socket does not have enough data available, it cycles on the recv() util the requested data (of size 'size') is arrived. In this case, it blocks until the number of bytes read is equal to 'size'. Parameters:
  sock: | the connected socket currently opened.
  buffer: | a char pointer to a user-allocated buffer in which data has to be stored
  size: | size of the allocated buffer. WARNING: this indicates the number of bytes that we are expecting to be read.
  receiveall: | if '0' (or SOCK_RECEIVEALL_NO), it returns as soon as some data is ready; otherwise, (or SOCK_RECEIVEALL_YES) it waits until 'size' data has been received (in case the socket does not have enough data available).
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: the number of bytes read if everything is fine, '-1' if some errors occurred. The error message is returned in the 'errbuf' variable. Definition at line 684 of file sockutils.c. References errbuf, size, snprintf, SOCK_ASSERT, and sock_geterror(). Referenced by daemon_checkauth(), daemon_opensource(), daemon_serviceloop(), daemon_setsampling(), daemon_startcapture(), daemon_unpackapplyfilter(), pcap_close_remote(), pcap_findalldevs_ex(), pcap_opensource_remote(), pcap_read_nocb_remote(), pcap_setsampling_remote(), pcap_startcapture_remote(), pcap_updatefilter_remote(), rpcap_checkmsg(), rpcap_sendauth(), rpcap_stats_remote(), and sock_discard().

int sock_send | ( | SOCKET | socket,
|  | const char * | buffer,
|  | int | size,
|  | char * | errbuf,
|  | int | errbuflen
| ) |

  | It sends the amount of data contained into 'buffer' on the given socket. This function basically calls the send() socket function and it checks that all the data specified in 'buffer' (of size 'size') will be sent. If an error occurs, it writes the error message into 'errbuf'. In case the socket buffer does not have enough space, it loops until all data has been sent. Parameters:
  socket: | the connected socket currently opened.
  buffer: | a char pointer to a user-allocated buffer in which data is contained.
  size: | number of bytes that have to be sent.
  errbuf: | a pointer to an user-allocated buffer that will contain the complete error message. This buffer has to be at least 'errbuflen' in length. It can be NULL; in this case the error cannot be printed.
  errbuflen: | length of the buffer that will contains the error. The error message cannot be larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
Returns: '0' if everything is fine, '-1' if some errors occurred. The error message is returned in the 'errbuf' variable. Definition at line 535 of file sockutils.c. References size, and sock_geterror(). Referenced by daemon_checkauth(), daemon_endcapture(), daemon_findalldevs(), daemon_getstats(), daemon_getstatsnopcap(), daemon_opensource(), daemon_setsampling(), daemon_startcapture(), daemon_thrdatamain(), daemon_updatefilter(), pcap_close_remote(), pcap_findalldevs_ex(), pcap_opensource_remote(), pcap_remoteact_close(), pcap_setsampling_remote(), pcap_startcapture_remote(), pcap_updatefilter_remote(), rpcap_sendauth(), rpcap_senderror(), and rpcap_stats_remote().

documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.