docs: fix new-applet-HOWTO.txt, delete ipv4_ipv6.txt (it's obsolete)
This commit is contained in:
parent
06200348be
commit
360362dc57
@ -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);
|
|
@ -46,6 +46,7 @@ int mu_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
|||||||
int mu_main(int argc, char **argv)
|
int mu_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
ssize_t n;
|
||||||
char mu;
|
char mu;
|
||||||
|
|
||||||
fd = xopen("/dev/random", O_RDONLY);
|
fd = xopen("/dev/random", O_RDONLY);
|
||||||
@ -123,7 +124,7 @@ lib-$(CONFIG_MU) += mu.o
|
|||||||
|
|
||||||
Add the applet to Config.in in the chosen directory:
|
Add the applet to Config.in in the chosen directory:
|
||||||
|
|
||||||
config CONFIG_MU
|
config MU
|
||||||
bool "MU"
|
bool "MU"
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
|
Loading…
Reference in New Issue
Block a user