11573Srgrimes/*
21573Srgrimes * Copyright (c) 1983, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 4. Neither the name of the University nor the names of its contributors
141573Srgrimes *    may be used to endorse or promote products derived from this software
151573Srgrimes *    without specific prior written permission.
161573Srgrimes *
171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271573Srgrimes * SUCH DAMAGE.
281573Srgrimes */
291573Srgrimes
301573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
311573Srgrimesstatic char sccsid[] = "@(#)getproto.c	8.1 (Berkeley) 6/4/93";
321573Srgrimes#endif /* LIBC_SCCS and not lint */
3392889Sobrien#include <sys/cdefs.h>
3492889Sobrien__FBSDID("$FreeBSD$");
351573Srgrimes
36211276Sume#include <errno.h>
371573Srgrimes#include <netdb.h>
38158115Sume#include <nsswitch.h>
39145279Sume#include "netdb_private.h"
40158115Sume#ifdef NS_CACHING
41158115Sume#include "nscache.h"
42158115Sume#endif
43158115Sume#include "nss_tls.h"
441573Srgrimes
45158115Sumestatic const ns_src defaultsrc[] = {
46158115Sume	{ NSSRC_FILES, NS_SUCCESS },
47158115Sume	{ NULL, 0 }
48158115Sume};
49158115Sume
50158115Sume#ifdef NS_CACHING
51158115Sumeextern int __proto_id_func(char *, size_t *, va_list, void *);
52158115Sumeextern int __proto_marshal_func(char *, size_t *, void *, va_list, void *);
53158115Sumeextern int __proto_unmarshal_func(char *, size_t, void *, va_list, void *);
54158115Sume#endif
55158115Sume
56158115Sumestatic int
57158115Sumefiles_getprotobynumber(void *retval, void *mdata, va_list ap)
58145279Sume{
59157779Sume	struct protoent pe;
60157779Sume	struct protoent_data *ped;
61145279Sume	int error;
621573Srgrimes
63158115Sume	int number;
64158115Sume	struct protoent	*pptr;
65158115Sume	char *buffer;
66158115Sume	size_t buflen;
67158115Sume	int *errnop;
68158115Sume
69158115Sume	number = va_arg(ap, int);
70158115Sume	pptr = va_arg(ap, struct protoent *);
71158115Sume	buffer = va_arg(ap, char *);
72158115Sume	buflen = va_arg(ap, size_t);
73158115Sume	errnop = va_arg(ap, int *);
74158115Sume
75158115Sume	if ((ped = __protoent_data_init()) == NULL) {
76211276Sume		*errnop = errno;
77158115Sume		return (NS_NOTFOUND);
78158115Sume	}
79158115Sume
80157779Sume	__setprotoent_p(ped->stayopen, ped);
81157779Sume	while ((error = __getprotoent_p(&pe, ped)) == 0)
82158115Sume		if (pe.p_proto == number)
83145279Sume			break;
84145279Sume	if (!ped->stayopen)
85157779Sume		__endprotoent_p(ped);
86158115Sume	if (error != 0) {
87211276Sume		*errnop = errno;
88158115Sume		return (NS_NOTFOUND);
89158115Sume	}
90158115Sume	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
91211276Sume		*errnop = errno;
92211276Sume		return (NS_RETURN);
93158115Sume	}
94158115Sume
95158115Sume	*((struct protoent **)retval) = pptr;
96158115Sume	return (NS_SUCCESS);
97145279Sume}
98145279Sume
99158115Sumeint
100158115Sumegetprotobynumber_r(int proto, struct protoent *pptr, char *buffer,
101158115Sume    size_t buflen, struct protoent **result)
102158115Sume{
103158115Sume#ifdef NS_CACHING
104158115Sume	static const nss_cache_info cache_info =
105158115Sume    		NS_COMMON_CACHE_INFO_INITIALIZER(
106158115Sume		protocols, (void *)nss_lt_id,
107158115Sume		__proto_id_func, __proto_marshal_func, __proto_unmarshal_func);
108158115Sume#endif
109158115Sume
110158115Sume	static const ns_dtab dtab[] = {
111158115Sume		{ NSSRC_FILES, files_getprotobynumber, NULL },
112158115Sume#ifdef NS_CACHING
113158115Sume		NS_CACHE_CB(&cache_info)
114158115Sume#endif
115158115Sume		{ NULL, NULL, NULL }
116158115Sume	};
117158115Sume	int	rv, ret_errno;
118158115Sume
119158115Sume	ret_errno = 0;
120158115Sume	*result = NULL;
121158115Sume	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotobynumber_r",
122158115Sume		defaultsrc, proto, pptr, buffer, buflen, &ret_errno);
123158115Sume
124211276Sume	if (rv != NS_SUCCESS) {
125211276Sume		errno = ret_errno;
126213453Sume		return (ret_errno);
127211276Sume	}
128211276Sume	return (0);
129158115Sume}
130158115Sume
1311573Srgrimesstruct protoent *
132145279Sumegetprotobynumber(int proto)
1331573Srgrimes{
134145279Sume	struct protodata *pd;
135157779Sume	struct protoent *rval;
1361573Srgrimes
137145279Sume	if ((pd = __protodata_init()) == NULL)
138145279Sume		return (NULL);
139157779Sume	if (getprotobynumber_r(proto, &pd->proto, pd->data, sizeof(pd->data),
140157779Sume	    &rval) != 0)
141145279Sume		return (NULL);
142157779Sume	return (rval);
1431573Srgrimes}
144