1183423Smarius/* $NetBSD: getaddrinfo_hostspec.c,v 1.2 2017/01/28 21:31:50 christos Exp $ */ 2183423Smarius 3183423Smarius/* 4183423Smarius * Copyright (c) 2000 Kungliga Tekniska H��gskolan 5183423Smarius * (Royal Institute of Technology, Stockholm, Sweden). 6183423Smarius * All rights reserved. 7183423Smarius * 8183423Smarius * Redistribution and use in source and binary forms, with or without 9183423Smarius * modification, are permitted provided that the following conditions 10183423Smarius * are met: 11183423Smarius * 12183423Smarius * 1. Redistributions of source code must retain the above copyright 13183423Smarius * notice, this list of conditions and the following disclaimer. 14183423Smarius * 15183423Smarius * 2. Redistributions in binary form must reproduce the above copyright 16183423Smarius * notice, this list of conditions and the following disclaimer in the 17183423Smarius * documentation and/or other materials provided with the distribution. 18183423Smarius * 19183423Smarius * 3. Neither the name of the Institute nor the names of its contributors 20183423Smarius * may be used to endorse or promote products derived from this software 21183423Smarius * without specific prior written permission. 22183423Smarius * 23183423Smarius * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24183423Smarius * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25183423Smarius * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26183423Smarius * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27183423Smarius * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28183423Smarius * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29183423Smarius * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30183423Smarius * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31183423Smarius * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32183423Smarius * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33183423Smarius * SUCH DAMAGE. 34220038Smarius */ 35220038Smarius 36220038Smarius#include <config.h> 37220038Smarius 38220038Smarius#include <krb5/roken.h> 39220038Smarius 40220038Smarius/* getaddrinfo via string specifying host and port */ 41183423Smarius 42220038SmariusROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 43220038Smariusroken_getaddrinfo_hostspec2(const char *hostspec, 44183423Smarius int socktype, 45183423Smarius int port, 46220038Smarius struct addrinfo **ai) 47220038Smarius{ 48220038Smarius const char *p; 49183423Smarius char portstr[NI_MAXSERV]; 50183423Smarius char host[MAXHOSTNAMELEN]; 51183423Smarius struct addrinfo hints; 52183423Smarius int hostspec_len; 53183423Smarius 54185133Smarius struct hst { 55185133Smarius const char *prefix; 56185133Smarius int socktype; 57183423Smarius int protocol; 58185133Smarius int port; 59208097Smarius } *hstp, hst[] = { 60220038Smarius { "http://", SOCK_STREAM, IPPROTO_TCP, 80 }, 61185133Smarius { "http/", SOCK_STREAM, IPPROTO_TCP, 80 }, 62185133Smarius { "tcp/", SOCK_STREAM, IPPROTO_TCP, 0 }, 63185133Smarius { "udp/", SOCK_DGRAM, IPPROTO_UDP, 0 }, 64220038Smarius { NULL, 0, 0, 0 } 65185133Smarius }; 66220038Smarius 67185133Smarius memset(&hints, 0, sizeof(hints)); 68183423Smarius 69183423Smarius hints.ai_socktype = socktype; 70183423Smarius 71220038Smarius for(hstp = hst; hstp->prefix; hstp++) { 72183423Smarius if(strncmp(hostspec, hstp->prefix, strlen(hstp->prefix)) == 0) { 73183423Smarius hints.ai_socktype = hstp->socktype; 74183423Smarius hints.ai_protocol = hstp->protocol; 75183423Smarius if(port == 0) 76183423Smarius port = hstp->port; 77220038Smarius hostspec += strlen(hstp->prefix); 78183423Smarius break; 79183423Smarius } 80183423Smarius } 81183423Smarius 82183423Smarius p = strchr (hostspec, ':'); 83183423Smarius if (p != NULL) { 84183423Smarius char *end; 85183423Smarius 86183423Smarius port = strtol (p + 1, &end, 0); 87208097Smarius hostspec_len = p - hostspec; 88208097Smarius } else { 89208097Smarius hostspec_len = strlen(hostspec); 90183423Smarius } 91201395Smarius snprintf (portstr, sizeof(portstr), "%u", port); 92183423Smarius 93183423Smarius snprintf (host, sizeof(host), "%.*s", hostspec_len, hostspec); 94183423Smarius return getaddrinfo (host, portstr, &hints, ai); 95183423Smarius} 96183423Smarius 97183423SmariusROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 98183423Smariusroken_getaddrinfo_hostspec(const char *hostspec, 99 int port, 100 struct addrinfo **ai) 101{ 102 return roken_getaddrinfo_hostspec2(hostspec, 0, port, ai); 103} 104