about summary refs log tree commit diff
path: root/src/network/lookup_serv.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-02-07 14:01:34 -0500
committerRich Felker <dalias@aerifal.cx>2015-02-07 14:01:34 -0500
commitc63c98a6067030a25a42703db1209ccbcc74803a (patch)
tree7ffaee240a0cf9286d851a1681d974878b2cf091 /src/network/lookup_serv.c
parente63833cd43a778f639e4fdf5d86cd5c526cc5db2 (diff)
downloadmusl-c63c98a6067030a25a42703db1209ccbcc74803a.tar.gz
musl-c63c98a6067030a25a42703db1209ccbcc74803a.tar.xz
musl-c63c98a6067030a25a42703db1209ccbcc74803a.zip
make getaddrinfo support SOCK_RAW and other socket types
all socket types are accepted at this point, but that may be changed
at a later time if the behavior is not meaningful for other types. as
before, omitting type (a value of 0) gives both UDP and TCP results,
and SOCK_DGRAM or SOCK_STREAM restricts to UDP or TCP, respectively.
for other socket types, the service name argument is required to be a
null pointer, and the protocol number provided by the caller is used.
Diffstat (limited to 'src/network/lookup_serv.c')
-rw-r--r--src/network/lookup_serv.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/network/lookup_serv.c b/src/network/lookup_serv.c
index a9be0f3d..4faa5bc7 100644
--- a/src/network/lookup_serv.c
+++ b/src/network/lookup_serv.c
@@ -7,13 +7,43 @@
 #include "lookup.h"
 #include "stdio_impl.h"
 
-int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int flags)
+int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags)
 {
 	char line[128];
 	int cnt = 0;
 	char *p, *z = "";
 	unsigned long port = 0;
 
+	switch (socktype) {
+	case SOCK_STREAM:
+		switch (proto) {
+		case 0:
+			proto = IPPROTO_TCP;
+		case IPPROTO_TCP:
+			break;
+		default:
+			return EAI_SERVICE;
+		}
+		break;
+	case SOCK_DGRAM:
+		switch (proto) {
+		case 0:
+			proto = IPPROTO_UDP;
+		case IPPROTO_UDP:
+			break;
+		default:
+			return EAI_SERVICE;
+		}
+	case 0:
+		break;
+	default:
+		if (name) return EAI_SERVICE;
+		buf[0].port = 0;
+		buf[0].proto = proto;
+		buf[0].socktype = socktype;
+		return 1;
+	}
+
 	if (name) {
 		if (!*name) return EAI_SERVICE;
 		port = strtoul(name, &z, 10);
@@ -22,10 +52,12 @@ int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int pro
 		if (port > 65535) return EAI_SERVICE;
 		if (proto != IPPROTO_UDP) {
 			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_STREAM;
 			buf[cnt++].proto = IPPROTO_TCP;
 		}
 		if (proto != IPPROTO_TCP) {
 			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_DGRAM;
 			buf[cnt++].proto = IPPROTO_UDP;
 		}
 		return cnt;
@@ -58,11 +90,13 @@ int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int pro
 		if (!strncmp(z, "/udp", 4)) {
 			if (proto == IPPROTO_TCP) continue;
 			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_DGRAM;
 			buf[cnt++].proto = IPPROTO_UDP;
 		}
 		if (!strncmp(z, "/tcp", 4)) {
 			if (proto == IPPROTO_UDP) continue;
 			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_STREAM;
 			buf[cnt++].proto = IPPROTO_TCP;
 		}
 	}