1/* $NetBSD: t_getprotoent.c,v 1.1 2011/07/15 06:41:29 jruoho Exp $ */
2
3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jukka Ruohonen.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31#include <sys/cdefs.h>
32__RCSID("$NetBSD: t_getprotoent.c,v 1.1 2011/07/15 06:41:29 jruoho Exp $");
33
34#include <atf-c.h>
35#include <netdb.h>
36#include <limits.h>
37#include <stdio.h>
38#include <string.h>
39
40static const struct {
41	const char *name;
42	int	    number;
43} protos[] = {
44
45	{ "icmp", 1 },	{ "tcp", 6 },	{ "udp", 17 },	{ "gre", 47 },
46	{ "esp", 50 },	{ "ah", 51 },	{ "sctp", 132},	{ "ipv6-icmp", 58 }
47};
48
49ATF_TC(endprotoent_rewind);
50ATF_TC_HEAD(endprotoent_rewind, tc)
51{
52	atf_tc_set_md_var(tc, "descr", "Check that endprotoent(3) rewinds");
53}
54
55ATF_TC_BODY(endprotoent_rewind, tc)
56{
57	struct protoent *p;
58	int i = 0;
59
60	setprotoent(0);
61
62	while ((p = getprotoent()) != NULL && i <= 10) {
63		ATF_REQUIRE(p->p_proto == i);
64		i++;
65	}
66
67	i = 0;
68	endprotoent();
69
70	while ((p = getprotoent()) != NULL && i <= 10) {
71		ATF_REQUIRE(p->p_proto == i);
72		i++;
73	}
74
75	endprotoent();
76}
77
78ATF_TC(getprotobyname_basic);
79ATF_TC_HEAD(getprotobyname_basic, tc)
80{
81	atf_tc_set_md_var(tc, "descr", "A naive test of getprotobyname(3)");
82}
83
84ATF_TC_BODY(getprotobyname_basic, tc)
85{
86	struct protoent *p;
87	size_t i;
88
89	for (i = 0; i < __arraycount(protos); i++) {
90
91		p = getprotobyname(protos[i].name);
92
93		ATF_REQUIRE(p != NULL);
94		ATF_REQUIRE(p->p_proto == protos[i].number);
95		ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0);
96	}
97
98	endprotoent();
99}
100
101ATF_TC(getprotobyname_err);
102ATF_TC_HEAD(getprotobyname_err, tc)
103{
104	atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobyname(3)");
105}
106
107ATF_TC_BODY(getprotobyname_err, tc)
108{
109	static const char * name[] =
110	    { "xxx", "yyy", "xyz", ".as.d}9x.._?!!#\xa4,\xa8^//&%%,",
111	      "0", "", "tCp", "uDp", "t c p", "tcp ", " tcp" };
112
113	size_t i;
114
115	for (i = 0; i < __arraycount(name); i++)
116		ATF_REQUIRE(getprotobyname(name[i]) == NULL);
117
118	endprotoent();
119}
120
121ATF_TC(getprotobynumber_basic);
122ATF_TC_HEAD(getprotobynumber_basic, tc)
123{
124	atf_tc_set_md_var(tc, "descr", "A naive test of getprotobynumber(3)");
125}
126
127ATF_TC_BODY(getprotobynumber_basic, tc)
128{
129	struct protoent *p;
130	size_t i;
131
132	/*
133	 * No ATF_CHECK() due static storage.
134	 */
135	for (i = 0; i < __arraycount(protos); i++) {
136
137		p = getprotobynumber(protos[i].number);
138
139		ATF_REQUIRE(p != NULL);
140		ATF_REQUIRE(p->p_proto == protos[i].number);
141		ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0);
142	}
143
144	endprotoent();
145}
146
147ATF_TC(getprotobynumber_err);
148ATF_TC_HEAD(getprotobynumber_err, tc)
149{
150	atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobynumber(3)");
151}
152
153ATF_TC_BODY(getprotobynumber_err, tc)
154{
155	static const int number[] = { -1, -99999, INT_MAX, 1000000000 };
156	size_t i;
157
158	for (i = 0; i < __arraycount(number); i++)
159		ATF_REQUIRE(getprotobynumber(number[i]) == NULL);
160
161	endprotoent();
162}
163
164ATF_TC(getprotoent_next);
165ATF_TC_HEAD(getprotoent_next, tc)
166{
167	atf_tc_set_md_var(tc, "descr", "getprotoent(3) returns next line?");
168}
169
170ATF_TC_BODY(getprotoent_next, tc)
171{
172	struct protoent *p;
173	int i = 0;
174
175	/*
176	 * The range [0, 60] is already reserved by IANA.
177	 */
178	while ((p = getprotoent()) != NULL && i <= 60) {
179		ATF_CHECK(p->p_proto == i);
180		i++;
181	}
182
183	endprotoent();
184}
185
186ATF_TC(setprotoent_rewind);
187ATF_TC_HEAD(setprotoent_rewind, tc)
188{
189	atf_tc_set_md_var(tc, "descr", "Check that setprotoent(3) rewinds");
190}
191
192ATF_TC_BODY(setprotoent_rewind, tc)
193{
194	struct protoent *p;
195
196	setprotoent(0);
197
198	p = getprotoent();
199	ATF_REQUIRE(p->p_proto == 0);
200
201	p = getprotoent();
202	ATF_REQUIRE(p->p_proto == 1);
203
204	p = getprotoent();
205	ATF_REQUIRE(p->p_proto == 2);
206
207	setprotoent(0);
208
209	p = getprotoent();
210	ATF_REQUIRE(p->p_proto == 0);
211
212	p = getprotoent();
213	ATF_REQUIRE(p->p_proto == 1);
214
215	p = getprotoent();
216	ATF_REQUIRE(p->p_proto == 2);
217
218	endprotoent();
219}
220
221ATF_TP_ADD_TCS(tp)
222{
223
224	ATF_TP_ADD_TC(tp, getprotobyname_basic);
225	ATF_TP_ADD_TC(tp, getprotobyname_err);
226	ATF_TP_ADD_TC(tp, getprotobynumber_basic);
227	ATF_TP_ADD_TC(tp, getprotobynumber_err);
228	ATF_TP_ADD_TC(tp, endprotoent_rewind);
229	ATF_TP_ADD_TC(tp, getprotoent_next);
230	ATF_TP_ADD_TC(tp, setprotoent_rewind);
231
232	return atf_no_error();
233}
234