diff options
Diffstat (limited to 'docs/ipv4_ipv6.txt')
-rw-r--r-- | docs/ipv4_ipv6.txt | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/docs/ipv4_ipv6.txt b/docs/ipv4_ipv6.txt deleted file mode 100644 index 92010b5..0000000 --- a/docs/ipv4_ipv6.txt +++ /dev/null @@ -1,223 +0,0 @@ -We need better network address conv helpers. -This is what our applets want: - - sockaddr -> hostname -udhcp: hostname -> ipv4 addr -nslookup: hostname -> list of names - done -tftp: host,port -> sockaddr -nc: host,port -> sockaddr -inetd: ? -traceroute: ?, hostname -> ipv4 addr -arping hostname -> ipv4 addr -ping6 hostname -> ipv6 addr -ifconfig hostname -> ipv4 addr (FIXME error check?) -ipcalc ipv4 addr -> hostname -syslogd hostname -> sockaddr -inet_common.c: buggy. hostname -> ipv4 addr -mount hostname -> sockaddr_in - -================== -HOWTO get rid of inet_ntoa/aton: - -foo.sin_addr.s_addr = inet_addr(cp); -- -inet_pton(AF_INET, cp, &foo.sin_addr); - -inet_aton(cp, &foo.sin_addr); -- -inet_pton(AF_INET, cp, &foo.sin_addr); - -ptr = inet_ntoa(foo.sin_addr); -- -char str[INET_ADDRSTRLEN]; -ptr = inet_ntop(AF_INET, &foo.sin_addr, str, sizeof(str)); - -=================== - - struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - struct sockaddr *ai_addr; - char *ai_canonname; - struct addrinfo *ai_next; - }; - int getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res); - - void freeaddrinfo(struct addrinfo *res); - - const char *gai_strerror(int errcode); - - The members ai_family, ai_socktype, and ai_protocol have the same meaning - as the corresponding parameters in the socket(2) system call. The getad- - drinfo(3) function returns socket addresses in either IPv4 or IPv6 address - family, (ai_family will be set to either AF_INET or AF_INET6). - - The hints parameter specifies the preferred socket type, or protocol. A - NULL hints specifies that any network address or protocol is acceptable. - If this parameter is not NULL it points to an addrinfo structure whose - ai_family, ai_socktype, and ai_protocol members specify the preferred - socket type. AF_UNSPEC in ai_family specifies any protocol family (either - IPv4 or IPv6, for example). 0 in ai_socktype or ai_protocol specifies - that any socket type or protocol is acceptable as well. The ai_flags mem- - ber specifies additional options, defined below. Multiple flags are spec- - ified by logically OR-ing them together. All the other members in the - hints parameter must contain either 0, or a null pointer. - - The node or service parameter, but not both, may be NULL. node specifies - either a numerical network address (dotted-decimal format for IPv4, hex- - adecimal format for IPv6) or a network hostname, whose network addresses - are looked up and resolved. If hints.ai_flags contains the AI_NUMERICHOST - flag then the node parameter must be a numerical network address. The - AI_NUMERICHOST flag suppresses any potentially lengthy network host - address lookups. - - The getaddrinfo(3) function creates a linked list of addrinfo structures, - one for each network address subject to any restrictions imposed by the - hints parameter. The ai_canonname field of the first of these addrinfo - structures is set to point to the official name of the host, if - hints.ai_flags includes the AI_CANONNAME flag. ai_family, ai_socktype, - and ai_protocol specify the socket creation parameters. A pointer to the - socket address is placed in the ai_addr member, and the length of the - socket address, in bytes, is placed in the ai_addrlen member. - - If node is NULL, the network address in each socket structure is initial- - ized according to the AI_PASSIVE flag, which is set in hints.ai_flags. - The network address in each socket structure will be left unspecified if - AI_PASSIVE flag is set. This is used by server applications, which intend - to accept client connections on any network address. The network address - will be set to the loopback interface address if the AI_PASSIVE flag is - not set. This is used by client applications, which intend to connect to - a server running on the same network host. - - If hints.ai_flags includes the AI_ADDRCONFIG flag, then IPv4 addresses are - returned in the list pointed to by result only if the local system has at - least has at least one IPv4 address configured, and IPv6 addresses are - only returned if the local system has at least one IPv6 address config- - ured. - - If hint.ai_flags specifies the AI_V4MAPPED flag, and hints.ai_family was - specified as AF_INET6, and no matching IPv6 addresses could be found, then - return IPv4-mapped IPv6 addresses in the list pointed to by result. If - both AI_V4MAPPED and AI_ALL are specified in hints.ai_family, then return - both IPv6 and IPv4-mapped IPv6 addresses in the list pointed to by result. - AI_ALL is ignored if AI_V4MAPPED is not also specified. - - service sets the port number in the network address of each socket struc- - ture. If service is NULL the port number will be left uninitialized. If - AI_NUMERICSERV is specified in hints.ai_flags and service is not NULL, - then service must point to a string containing a numeric port number. - This flag is used to inhibit the invocation of a name resolution service - in cases where it is known not to be required. - - -============== - - int getnameinfo(const struct sockaddr *sa, socklen_t salen, - char *host, size_t hostlen, - char *serv, size_t servlen, int flags); - - The getnameinfo(3) function is defined for protocol-independent - address-to-nodename translation. It combines the functionality - of gethostbyaddr(3) and getservbyport(3) and is the inverse of - getaddrinfo(3). The sa argument is a pointer to a generic socket address - structure (of type sockaddr_in or sockaddr_in6) of size salen that - holds the input IP address and port number. The arguments host and - serv are pointers to buffers (of size hostlen and servlen respectively) - to hold the return values. - - The caller can specify that no hostname (or no service name) is required - by providing a NULL host (or serv) argument or a zero hostlen (or servlen) - parameter. However, at least one of hostname or service name must be requested. - - The flags argument modifies the behaviour of getnameinfo(3) as follows: - - NI_NOFQDN - If set, return only the hostname part of the FQDN for local hosts. - - NI_NUMERICHOST - If set, then the numeric form of the hostname is returned. - (When not set, this will still happen in case the node's name - cannot be looked up.) - - NI_NAMEREQD - If set, then a error is returned if the hostname cannot be looked up. - - NI_NUMERICSERV - If set, then the service address is returned in numeric form, - for example by its port number. - - NI_DGRAM - If set, then the service is datagram (UDP) based rather than stream - (TCP) based. This is required for the few ports (512-514) that have different - services for UDP and TCP. - -================= - -Modified IPv6-aware C code: - - struct addrinfo *res, *aip; - struct addrinfo hints; - int sock = -1; - int error; - - /* Get host address. Any type of address will do. */ - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_ALL|AI_ADDRCONFIG; - hints.ai_socktype = SOCK_STREAM; - - error = getaddrinfo(hostname, servicename, &hints, &res); - if (error != 0) { - (void) fprintf(stderr, - "getaddrinfo: %s for host %s service %s\n", - gai_strerror(error), hostname, servicename); - return -1; - } - /* Try all returned addresses until one works */ - for (aip = res; aip != NULL; aip = aip->ai_next) { - /* - * Open socket. The address type depends on what - * getaddrinfo() gave us. - */ - sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); - if (sock == -1) { - perror("socket"); - freeaddrinfo(res); - return -1; - } - - /* Connect to the host. */ - if (connect(sock, aip->ai_addr, aip->ai_addrlen) == -1) { - perror("connect"); - (void) close(sock); - sock = -1; - continue; - } - break; - } - freeaddrinfo(res); - -Note that for new applications, if you write address-family-agnostic data structures, -there is no need for porting. - -However, when it comes to server-side programming in C/C++, there is an additional wrinkle. -Namely, depending on whether your application is written for a dual-stack platform, such -as Solaris or Linux, or a single-stack platform, such as Windows, you would need to -structure the code differently. - -Here's the corresponding server C code for a dual-stack platform: - - int ServSock, csock; - /* struct sockaddr is too small! */ - struct sockaddr_storage addr, from; - ... - ServSock = socket(AF_INET6, SOCK_STREAM, PF_INET6); - bind(ServSock, &addr, sizeof(addr)); - do { - csock = accept(ServSocket, &from, sizeof(from)); - doClientStuff(csock); - } while (!finished); |