summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am53
-rw-r--r--plugins/getaddrinfo.c303
-rw-r--r--plugins/getaddrinfo.h68
-rw-r--r--plugins/gethostbyname.c228
-rw-r--r--plugins/gethostbyname.h103
-rw-r--r--plugins/netutils.c83
-rw-r--r--plugins/netutils.h13
-rw-r--r--plugins/utils.c81
-rw-r--r--plugins/utils.h8
9 files changed, 810 insertions, 130 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 2524e1a..a884b45 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -14,14 +14,15 @@ EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \
14 check_swap check_fping check_ldap check_game check_dig \ 14 check_swap check_fping check_ldap check_game check_dig \
15 check_nagios check_by_ssh check_dns check_nt 15 check_nagios check_by_ssh check_dns check_nt
16 16
17check_tcp_programs = check_ftp check_imap check_nntp check_pop 17check_tcp_programs = check_ftp check_imap check_nntp check_pop check_udp2
18 18
19EXTRA_DIST = t utils.c netutils.c popen.c utils.h netutils.h popen.h common.h 19EXTRA_DIST = t utils.c netutils.c popen.c utils.h netutils.h popen.h common.h \
20 getaddrinfo.c getaddrinfo.h gethostbyname.c gethostbyname.h
20 21
21PLUGINHDRS = common.h config.h 22PLUGINHDRS = common.h config.h
22 23
23BASEOBJS = utils.o ../lib/libnagiosplug.a 24BASEOBJS = utils.o ../lib/libnagiosplug.a
24NETOBJS = netutils.o $(BASEOBJS) 25NETOBJS = netutils.o $(BASEOBJS) $(EXTRA_NETOBJS)
25NETLIBS = $(NETOBJS) $(SOCKETLIBS) 26NETLIBS = $(NETOBJS) $(SOCKETLIBS)
26 27
27TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir) 28TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir)
@@ -36,27 +37,27 @@ AM_INSTALL_PROGRAM_FLAGS = @INSTALL_OPTS@
36############################################################################## 37##############################################################################
37# the actual targets 38# the actual targets
38 39
39check_dig_LDADD = $(BASEOBJS) popen.o 40check_dig_LDADD = $(NETLIBS) popen.o
40check_disk_LDADD = $(BASEOBJS) popen.o 41check_disk_LDADD = $(BASEOBJS) popen.o
41check_dns_LDADD = $(BASEOBJS) popen.o 42check_dns_LDADD = $(NETLIBS) popen.o
42check_dummy_LDADD = $(BASEOBJS) 43check_dummy_LDADD = $(BASEOBJS)
43check_fping_LDADD = $(BASEOBJS) popen.o 44check_fping_LDADD = $(NETLIBS) popen.o
44check_game_LDADD = $(BASEOBJS) 45check_game_LDADD = $(BASEOBJS)
45check_http_LDADD = $(NETLIBS) $(SSLLIBS) 46check_http_LDADD = $(NETLIBS) $(SSLLIBS)
46check_hpjd_LDADD = $(BASEOBJS) popen.o 47check_hpjd_LDADD = $(NETLIBS) popen.o
47check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS) 48check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS)
48check_load_LDADD = $(BASEOBJS) popen.o 49check_load_LDADD = $(BASEOBJS) popen.o
49check_mrtg_LDADD = $(BASEOBJS) 50check_mrtg_LDADD = $(BASEOBJS)
50check_mrtgtraf_LDADD = $(BASEOBJS) 51check_mrtgtraf_LDADD = $(BASEOBJS)
51check_mysql_LDADD = $(BASEOBJS) $(MYSQLLIBS) 52check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS)
52check_nagios_LDADD = $(BASEOBJS) popen.o 53check_nagios_LDADD = $(BASEOBJS) popen.o
53check_nt_LDADD = $(NETLIBS) 54check_nt_LDADD = $(NETLIBS)
54check_nwstat_LDADD = $(NETLIBS) 55check_nwstat_LDADD = $(NETLIBS)
55check_overcr_LDADD = $(NETLIBS) 56check_overcr_LDADD = $(NETLIBS)
56check_pgsql_LDADD = $(BASEOBJS) $(PGLIBS) 57check_pgsql_LDADD = $(NETLIBS) $(PGLIBS)
57check_ping_LDADD = $(BASEOBJS) popen.o 58check_ping_LDADD = $(NETLIBS) popen.o
58check_procs_LDADD = $(BASEOBJS) popen.o 59check_procs_LDADD = $(BASEOBJS) popen.o
59check_radius_LDADD = $(BASEOBJS) $(RADIUSLIBS) 60check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS)
60check_real_LDADD = $(NETLIBS) 61check_real_LDADD = $(NETLIBS)
61check_snmp_LDADD = $(BASEOBJS) popen.o 62check_snmp_LDADD = $(BASEOBJS) popen.o
62check_smtp_LDADD = $(NETLIBS) 63check_smtp_LDADD = $(NETLIBS)
@@ -68,31 +69,31 @@ check_udp_LDADD = $(NETLIBS)
68check_ups_LDADD = $(NETLIBS) 69check_ups_LDADD = $(NETLIBS)
69check_users_LDADD = $(BASEOBJS) popen.o 70check_users_LDADD = $(BASEOBJS) popen.o
70check_vsz_LDADD = $(BASEOBJS) popen.o 71check_vsz_LDADD = $(BASEOBJS) popen.o
71check_by_ssh_LDADD = $(BASEOBJS) popen.o 72check_by_ssh_LDADD = $(NETLIBS) popen.o
72negate_LDADD = $(BASEOBJS) popen.o 73negate_LDADD = $(BASEOBJS) popen.o
73urlize_LDADD = $(BASEOBJS) popen.o 74urlize_LDADD = $(BASEOBJS) popen.o
74 75
75check_dig_DEPENDENCIES = check_dig.c $(BASEOBJS) popen.o $(DEPLIBS) 76check_dig_DEPENDENCIES = check_dig.c $(NETOBJS) popen.o $(DEPLIBS)
76check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) popen.o $(DEPLIBS) 77check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) popen.o $(DEPLIBS)
77check_dns_DEPENDENCIES = check_dns.c $(BASEOBJS) popen.o $(DEPLIBS) 78check_dns_DEPENDENCIES = check_dns.c $(NETOBJS) popen.o $(DEPLIBS)
78check_dummy_DEPENDENCIES = check_dummy.c $(DEPLIBS) 79check_dummy_DEPENDENCIES = check_dummy.c $(DEPLIBS)
79check_fping_DEPENDENCIES = check_fping.c $(BASEOBJS) popen.o $(DEPLIBS) 80check_fping_DEPENDENCIES = check_fping.c $(NETOBJS) popen.o $(DEPLIBS)
80check_game_DEPENDENCIES = check_game.c $(DEPLIBS) 81check_game_DEPENDENCIES = check_game.c $(DEPLIBS)
81check_http_DEPENDENCIES = check_http.c $(NETOBJS) $(DEPLIBS) 82check_http_DEPENDENCIES = check_http.c $(NETOBJS) $(DEPLIBS)
82check_hpjd_DEPENDENCIES = check_hpjd.c $(BASEOBJS) popen.o $(DEPLIBS) 83check_hpjd_DEPENDENCIES = check_hpjd.c $(NETOBJS) popen.o $(DEPLIBS)
83check_ldap_DEPENDENCIES = check_ldap.c $(NETOBJS) $(DEPLIBS) 84check_ldap_DEPENDENCIES = check_ldap.c $(NETOBJS) $(DEPLIBS)
84check_load_DEPENDENCIES = check_load.c $(BASEOBJS) popen.o $(DEPLIBS) 85check_load_DEPENDENCIES = check_load.c $(BASEOBJS) popen.o $(DEPLIBS)
85check_mrtg_DEPENDENCIES = check_mrtg.c $(DEPLIBS) 86check_mrtg_DEPENDENCIES = check_mrtg.c $(DEPLIBS)
86check_mrtgtraf_DEPENDENCIES = check_mrtgtraf.c $(DEPLIBS) 87check_mrtgtraf_DEPENDENCIES = check_mrtgtraf.c $(DEPLIBS)
87check_mysql_DEPENDENCIES = check_mysql.c $(DEPLIBS) 88check_mysql_DEPENDENCIES = check_mysql.c $(NETOBJS) $(DEPLIBS)
88check_nagios_DEPENDENCIES = check_nagios.c $(BASEOBJS) popen.o $(DEPLIBS) 89check_nagios_DEPENDENCIES = check_nagios.c $(BASEOBJS) popen.o $(DEPLIBS)
89check_nt_DEPENDENCIES = check_nt.c $(NETOBJS) $(DEPLIBS) 90check_nt_DEPENDENCIES = check_nt.c $(NETOBJS) $(DEPLIBS)
90check_nwstat_DEPENDENCIES = check_nwstat.c $(NETOBJS) $(DEPLIBS) 91check_nwstat_DEPENDENCIES = check_nwstat.c $(NETOBJS) $(DEPLIBS)
91check_overcr_DEPENDENCIES = check_overcr.c $(NETOBJS) $(DEPLIBS) 92check_overcr_DEPENDENCIES = check_overcr.c $(NETOBJS) $(DEPLIBS)
92check_pgsql_DEPENDENCIES = check_pgsql.c $(DEPLIBS) 93check_pgsql_DEPENDENCIES = check_pgsql.c $(NETOBJS) $(DEPLIBS)
93check_ping_DEPENDENCIES = check_ping.c $(BASEOBJS) popen.o $(DEPLIBS) 94check_ping_DEPENDENCIES = check_ping.c $(NETOBJS) popen.o $(DEPLIBS)
94check_procs_DEPENDENCIES = check_procs.c $(BASEOBJS) popen.o $(DEPLIBS) 95check_procs_DEPENDENCIES = check_procs.c $(BASEOBJS) popen.o $(DEPLIBS)
95check_radius_DEPENDENCIES = check_radius.c $(DEPLIBS) 96check_radius_DEPENDENCIES = check_radius.c $(NETOBJS) $(DEPLIBS)
96check_real_DEPENDENCIES = check_real.c $(NETOBJS) $(DEPLIBS) 97check_real_DEPENDENCIES = check_real.c $(NETOBJS) $(DEPLIBS)
97check_snmp_DEPENDENCIES = check_snmp.c $(BASEOBJS) popen.o $(DEPLIBS) 98check_snmp_DEPENDENCIES = check_snmp.c $(BASEOBJS) popen.o $(DEPLIBS)
98check_smtp_DEPENDENCIES = check_smtp.c $(NETOBJS) $(DEPLIBS) 99check_smtp_DEPENDENCIES = check_smtp.c $(NETOBJS) $(DEPLIBS)
@@ -104,7 +105,7 @@ check_udp_DEPENDENCIES = check_udp.c $(NETOBJS) $(DEPLIBS)
104check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS) 105check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS)
105check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS) 106check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS)
106check_vsz_DEPENDENCIES = check_vsz.c $(BASEOBJS) popen.o $(DEPLIBS) 107check_vsz_DEPENDENCIES = check_vsz.c $(BASEOBJS) popen.o $(DEPLIBS)
107check_by_ssh_DEPENDENCIES = check_by_ssh.c $(BASEOBJS) popen.o $(DEPLIBS) 108check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) popen.o $(DEPLIBS)
108negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS) 109negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS)
109urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS) 110urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS)
110 111
@@ -117,6 +118,10 @@ utils.o: utils.c utils.h $(PLUGINHDRS)
117 118
118netutils.o: netutils.c netutils.h $(PLUGINHDRS) 119netutils.o: netutils.c netutils.h $(PLUGINHDRS)
119 120
121getaddrinfo.o: getaddrinfo.h $(PLUGINHDRS)
122
123gethostbyname.o: gethostbyname.h $(PLUGINHDRS)
124
120all-local: $(check_tcp_programs) 125all-local: $(check_tcp_programs)
121 126
122$(check_tcp_programs): check_tcp 127$(check_tcp_programs): check_tcp
diff --git a/plugins/getaddrinfo.c b/plugins/getaddrinfo.c
new file mode 100644
index 0000000..12ac67d
--- /dev/null
+++ b/plugins/getaddrinfo.c
@@ -0,0 +1,303 @@
1/*
2 * This file is part of libESMTP, a library for submission of RFC 2822
3 * formatted electronic mail messages using the SMTP protocol described
4 * in RFC 2821.
5 * Modified by Jeremy T. Bouse for use in Nagios plugins
6 *
7 * Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24/* An emulation of the RFC 2553 / Posix getaddrinfo resolver interface.
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30
31/* Need to turn off Posix features in glibc to build this */
32#undef _POSIX_C_SOURCE
33#undef _XOPEN_SOURCE
34
35#include <stdlib.h>
36#include <string.h>
37#include <ctype.h>
38#include <errno.h>
39
40#include <sys/socket.h>
41#include <netinet/in.h>
42#include <arpa/inet.h>
43
44#include <netdb.h>
45
46#include "gethostbyname.h"
47#include "getaddrinfo.h"
48
49static struct addrinfo *
50dup_addrinfo (struct addrinfo *info, void *addr, size_t addrlen)
51{
52 struct addrinfo *ret;
53
54 ret = malloc (sizeof (struct addrinfo));
55 if (ret == NULL)
56 return NULL;
57 memcpy (ret, info, sizeof (struct addrinfo));
58 ret->ai_addr = malloc (addrlen);
59 if (ret->ai_addr == NULL)
60 {
61 free (ret);
62 return NULL;
63 }
64 memcpy (ret->ai_addr, addr, addrlen);
65 ret->ai_addrlen = addrlen;
66 return ret;
67}
68
69int
70getaddrinfo (const char *nodename, const char *servname,
71 const struct addrinfo *hints, struct addrinfo **res)
72{
73 struct hostent *hp;
74 struct servent *servent;
75 const char *socktype;
76 int port;
77 struct addrinfo hint, result;
78 struct addrinfo *ai, *sai, *eai;
79 struct ghbnctx ghbnctx;
80 char **addrs;
81 int code;
82
83 memset (&result, 0, sizeof result);
84
85 /* default for hints */
86 if (hints == NULL)
87 {
88 memset (&hint, 0, sizeof hint);
89 hint.ai_family = PF_UNSPEC;
90 hints = &hint;
91 }
92
93 result.ai_socktype = hints->ai_socktype;
94
95 /* Note: maintain port in host byte order to make debugging easier */
96 if (servname != NULL) {
97 if (isdigit (*servname))
98 port = strtol (servname, NULL, 10);
99 else if ((servent = getservbyname (servname, socktype)) != NULL)
100 port = ntohs (servent->s_port);
101 else
102 return EAI_NONAME;
103 }
104
105 /* if nodename == NULL refer to the local host for a client or any
106 for a server */
107 if (nodename == NULL)
108 {
109 struct sockaddr_in sin;
110
111 /* check protocol family is PF_UNSPEC or PF_INET - could try harder
112 for IPv6 but that's more code than I'm prepared to write */
113 if (hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET)
114 result.ai_family = AF_INET;
115 else
116 return EAI_FAMILY;
117
118 sin.sin_family = result.ai_family;
119 sin.sin_port = htons (port);
120 if (hints->ai_flags & AI_PASSIVE)
121 sin.sin_addr.s_addr = htonl (INADDR_ANY);
122 else
123 sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
124 /* Duplicate result and addr and return */
125 *res = dup_addrinfo (&result, &sin, sizeof sin);
126 return (*res == NULL) ? EAI_MEMORY : 0;
127 }
128
129 /* If AI_NUMERIC is specified, use inet_addr to translate numbers and
130 dots notation. */
131 if (hints->ai_flags & AI_NUMERICHOST)
132 {
133 struct sockaddr_in sin;
134
135 /* check protocol family is PF_UNSPEC or PF_INET */
136 if (hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET)
137 result.ai_family = AF_INET;
138 else
139 return EAI_FAMILY;
140
141 sin.sin_family = result.ai_family;
142 sin.sin_port = htons (port);
143 sin.sin_addr.s_addr = inet_addr (nodename);
144 /* Duplicate result and addr and return */
145 *res = dup_addrinfo (&result, &sin, sizeof sin);
146 return (*res == NULL) ? EAI_MEMORY : 0;
147 }
148
149 errno = 0;
150 hp = gethostbyname_ctx (nodename, &ghbnctx);
151 if (hp == NULL)
152 {
153 if (errno != 0)
154 {
155 free_ghbnctx (&ghbnctx);
156 return EAI_SYSTEM;
157 }
158 code = h_error_ctx (&ghbnctx);
159 switch (code)
160 {
161 case HOST_NOT_FOUND: code = EAI_NODATA; break;
162 case NO_DATA: code = EAI_NODATA; break;
163#if defined(NO_ADDRESS) && NO_ADDRESS != NO_DATA
164 case NO_ADDRESS: code = EAI_NODATA; break;
165#endif
166 case NO_RECOVERY: code = EAI_FAIL; break;
167 case TRY_AGAIN: code = EAI_AGAIN; break;
168 default: code = EAI_FAIL; break;
169 }
170 free_ghbnctx (&ghbnctx);
171 return code;
172 }
173
174 /* Check that the address family is acceptable.
175 */
176 switch (hp->h_addrtype)
177 {
178 case AF_INET:
179 if (!(hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET))
180 goto eai_family;
181 break;
182#ifdef USE_IPV6
183 case AF_INET6:
184 if (!(hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET6))
185 goto eai_family;
186 break;
187#endif
188 default:
189 eai_family:
190 free_ghbnctx (&ghbnctx);
191 return EAI_FAMILY;
192 }
193
194 /* For each element pointed to by hp, create an element in the
195 result linked list. */
196 sai = eai = NULL;
197 for (addrs = hp->h_addr_list; *addrs != NULL; addrs++)
198 {
199 struct sockaddr sa;
200 size_t addrlen;
201
202 sa.sa_family = hp->h_addrtype;
203 switch (hp->h_addrtype)
204 {
205 case AF_INET:
206 ((struct sockaddr_in *) &sa)->sin_port = htons (port);
207 memcpy (&((struct sockaddr_in *) &sa)->sin_addr,
208 *addrs, hp->h_length);
209 addrlen = sizeof (struct sockaddr_in);
210 break;
211#ifdef USE_IPV6
212 case AF_INET6:
213# if SIN6_LEN
214 ((struct sockaddr_in6 *) &sa)->sin6_len = hp->h_length;
215# endif
216 ((struct sockaddr_in6 *) &sa)->sin6_port = htons (port);
217 memcpy (&((struct sockaddr_in6 *) &sa)->sin6_addr,
218 *addrs, hp->h_length);
219 addrlen = sizeof (struct sockaddr_in6);
220 break;
221#endif
222 default:
223 continue;
224 }
225
226 result.ai_family = hp->h_addrtype;
227 ai = dup_addrinfo (&result, &sa, addrlen);
228 if (ai == NULL)
229 {
230 free_ghbnctx (&ghbnctx);
231 freeaddrinfo (sai);
232 return EAI_MEMORY;
233 }
234 if (sai == NULL)
235 sai = ai;
236 else
237 eai->ai_next = ai;
238 eai = ai;
239 }
240
241 if (sai == NULL)
242 {
243 free_ghbnctx (&ghbnctx);
244 return EAI_NODATA;
245 }
246
247 if (hints->ai_flags & AI_CANONNAME)
248 {
249 sai->ai_canonname = malloc (strlen (hp->h_name) + 1);
250 if (sai->ai_canonname == NULL)
251 {
252 free_ghbnctx (&ghbnctx);
253 freeaddrinfo (sai);
254 return EAI_MEMORY;
255 }
256 strcpy (sai->ai_canonname, hp->h_name);
257 }
258
259 free_ghbnctx (&ghbnctx);
260 *res = sai;
261 return 0;
262}
263
264void
265freeaddrinfo (struct addrinfo *ai)
266{
267 struct addrinfo *next;
268
269 while (ai != NULL)
270 {
271 next = ai->ai_next;
272 if (ai->ai_canonname != NULL)
273 free (ai->ai_canonname);
274 if (ai->ai_addr != NULL)
275 free (ai->ai_addr);
276 free (ai);
277 ai = next;
278 }
279}
280
281const char *
282gai_strerror (int ecode)
283{
284 static const char *eai_descr[] =
285 {
286 "no error",
287 "address family for nodename not supported", /* EAI_ADDRFAMILY */
288 "temporary failure in name resolution", /* EAI_AGAIN */
289 "invalid value for ai_flags", /* EAI_BADFLAGS */
290 "non-recoverable failure in name resolution", /* EAI_FAIL */
291 "ai_family not supported", /* EAI_FAMILY */
292 "memory allocation failure", /* EAI_MEMORY */
293 "no address associated with nodename", /* EAI_NODATA */
294 "nodename nor servname provided, or not known", /* EAI_NONAME */
295 "servname not supported for ai_socktype", /* EAI_SERVICE */
296 "ai_socktype not supported", /* EAI_SOCKTYPE */
297 "system error returned in errno", /* EAI_SYSTEM */
298 };
299
300 if (ecode < 0 || ecode > (int) (sizeof eai_descr/ sizeof eai_descr[0]))
301 return "unknown error";
302 return eai_descr[ecode];
303}
diff --git a/plugins/getaddrinfo.h b/plugins/getaddrinfo.h
new file mode 100644
index 0000000..5bcc884
--- /dev/null
+++ b/plugins/getaddrinfo.h
@@ -0,0 +1,68 @@
1#ifndef _getaddrinfo_h
2#define _getaddrinfo_h
3/*
4 * This file is part of libESMTP, a library for submission of RFC 2822
5 * formatted electronic mail messages using the SMTP protocol described
6 * in RFC 2821.
7 * Modified by Jeremy T. Bouse for use in Nagios plugins
8 *
9 * Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26/* Structure and prototypes aken from RFC 2553 */
27
28struct addrinfo
29 {
30 int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
31 int ai_family; /* PF_xxx */
32 int ai_socktype; /* SOCK_xxx */
33 int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
34 size_t ai_addrlen; /* length of ai_addr */
35 char *ai_canonname; /* canonical name for nodename */
36 struct sockaddr *ai_addr; /* binary address */
37 struct addrinfo *ai_next; /* next structure in linked list */
38 };
39
40/* Supposed to be defined in <netdb.h> */
41#define AI_PASSIVE 1 /* Socket address is intended for `bind'. */
42#define AI_CANONNAME 2 /* Request for canonical name. */
43#define AI_NUMERICHOST 4 /* Don't use name resolution. */
44
45/* Supposed to be defined in <netdb.h> */
46#define EAI_ADDRFAMILY 1 /* address family for nodename not supported */
47#define EAI_AGAIN 2 /* temporary failure in name resolution */
48#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
49#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
50#define EAI_FAMILY 5 /* ai_family not supported */
51#define EAI_MEMORY 6 /* memory allocation failure */
52#define EAI_NODATA 7 /* no address associated with nodename */
53#define EAI_NONAME 8 /* nodename nor servname provided, or not known */
54#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
55#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
56#define EAI_SYSTEM 11 /* system error returned in errno */
57
58/* RFC 2553 / Posix resolver */
59int getaddrinfo (const char *nodename, const char *servname,
60 const struct addrinfo *hints, struct addrinfo **res);
61
62/* Free addrinfo structure and associated storage */
63void freeaddrinfo (struct addrinfo *ai);
64
65/* Convert error return from getaddrinfo() to string */
66const char *gai_strerror (int code);
67
68#endif
diff --git a/plugins/gethostbyname.c b/plugins/gethostbyname.c
new file mode 100644
index 0000000..d151606
--- /dev/null
+++ b/plugins/gethostbyname.c
@@ -0,0 +1,228 @@
1/*
2 * This file is a ghastly hack because nobody can agree on
3 * gethostbyname_r()'s prototype.
4 *
5 * Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
26#define _SVID_SOURCE 1 /* Need this to get gethostbyname_r() */
27
28#include <assert.h>
29
30#include <stdlib.h>
31#include <string.h>
32#include <netdb.h>
33#include <errno.h>
34
35#include "gethostbyname.h"
36
37#if HAVE_GETIPNODEBYNAME
38
39void
40free_ghbnctx (struct ghbnctx *ctx)
41{
42 assert (ctx != NULL);
43
44 if (ctx->hostent != NULL)
45 freehostent (ctx->hostent);
46}
47
48struct hostent *
49gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
50{
51 assert (ctx != NULL);
52
53 memset (ctx, 0, sizeof (struct ghbnctx));
54 ctx->hostent = getipnodebyname (host, AF_UNSPEC, AI_ADDRCONFIG, &ctx->h_err);
55 return ctx->hostent;
56}
57
58int
59h_error_ctx (struct ghbnctx *ctx)
60{
61 assert (ctx != NULL);
62
63 return ctx->h_err;
64}
65
66#elif HAVE_GETHOSTBYNAME_R == 6
67
68void
69free_ghbnctx (struct ghbnctx *ctx)
70{
71 assert (ctx != NULL);
72
73 if (ctx->hostbuf != NULL)
74 free (ctx->hostbuf);
75}
76
77struct hostent *
78gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
79{
80 struct hostent *hp;
81 char *tmp;
82 int err;
83
84 assert (ctx != NULL);
85
86 memset (ctx, 0, sizeof (struct ghbnctx));
87 ctx->hostbuf_len = 2048;
88 if ((ctx->hostbuf = malloc (ctx->hostbuf_len)) == NULL)
89 {
90 errno = ENOMEM;
91 return NULL;
92 }
93 while ((err = gethostbyname_r (host,
94 &ctx->hostent, ctx->hostbuf, ctx->hostbuf_len,
95 &hp, &ctx->h_err)) == ERANGE)
96 {
97 ctx->hostbuf_len += 1024;
98 if ((tmp = realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL)
99 {
100 errno = ENOMEM;
101 return NULL;
102 }
103 ctx->hostbuf = tmp;
104 }
105 if (err != 0)
106 {
107 errno = err;
108 return NULL;
109 }
110 return hp;
111}
112
113int
114h_error_ctx (struct ghbnctx *ctx)
115{
116 assert (ctx != NULL);
117
118 return ctx->h_err;
119}
120
121#elif HAVE_GETHOSTBYNAME_R == 5
122
123void
124free_ghbnctx (struct ghbnctx *ctx)
125{
126 assert (ctx != NULL);
127
128 if (ctx->hostbuf != NULL)
129 free (ctx->hostbuf);
130}
131
132struct hostent *
133gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
134{
135 struct hostent *hp;
136 char *tmp;
137
138 assert (ctx != NULL);
139
140 memset (ctx, 0, sizeof (struct ghbnctx));
141 ctx->hostbuf_len = 2048;
142 if ((ctx->hostbuf = malloc (ctx->hostbuf_len)) == NULL)
143 {
144 errno = ENOMEM;
145 return NULL;
146 }
147 while ((hp = gethostbyname_r (host, &ctx->hostent,
148 ctx->hostbuf, ctx->hostbuf_len,
149 &ctx->h_err)) == NULL && errno == ERANGE)
150 {
151 ctx->hostbuf_len += 1024;
152 if ((tmp = realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL)
153 {
154 errno = ENOMEM;
155 return NULL;
156 }
157 ctx->hostbuf = tmp;
158 }
159 return hp;
160}
161
162int
163h_error_ctx (struct ghbnctx *ctx)
164{
165 assert (ctx != NULL);
166
167 return ctx->h_err;
168}
169
170#elif HAVE_GETHOSTBYNAME_R == 3
171
172void
173free_ghbnctx (struct ghbnctx *ctx)
174{
175 assert (ctx != NULL);
176
177 /* FIXME: does this need to do anything? */
178}
179
180struct hostent *
181gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
182{
183 assert (ctx != NULL);
184
185 if (!gethostbyname_r (host, &ctx->hostent, &ctx->hostent_data))
186 {
187 ctx->h_err = h_errno; /* FIXME: is this correct? */
188 return NULL;
189 }
190 return &ctx->hostent;
191}
192
193int
194h_error_ctx (struct ghbnctx *ctx)
195{
196 assert (ctx != NULL);
197
198 return ctx->h_err;
199}
200
201#else
202
203void
204free_ghbnctx (struct ghbnctx *ctx __attribute__ ((unused)))
205{
206 assert (ctx != NULL);
207}
208
209struct hostent *
210gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
211{
212 struct hostent *hp;
213
214 hp = gethostbyname (host);
215 if (hp == NULL)
216 ctx->h_err = h_errno;
217 return hp;
218}
219
220int
221h_error_ctx (struct ghbnctx *ctx)
222{
223 assert (ctx != NULL);
224
225 return ctx->h_err;
226}
227
228#endif
diff --git a/plugins/gethostbyname.h b/plugins/gethostbyname.h
new file mode 100644
index 0000000..2b96399
--- /dev/null
+++ b/plugins/gethostbyname.h
@@ -0,0 +1,103 @@
1/*
2 * This file is a ghastly hack because nobody can agree on
3 * gethostbyname_r()'s prototype.
4 *
5 * Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22/*************************************************************************
23 Usage:
24
25 #include <errno.h>
26 #include "gethostbyname.h"
27
28 f ()
29 {
30 struct ghbnctx ctx;
31
32 errno = 0;
33 hp = gethostbyname_ctx (host, &ctx);
34 if (hp == NULL)
35 {
36 if (errno != 0)
37 handle_value_of_errno (errno);
38 else
39 handle_value_of_h_errno (h_error_ctx (&ctx));
40 }
41 else
42 {
43 ...
44 }
45 free_ghbnctx (&ctx);
46 }
47 *************************************************************************/
48
49#ifndef _gethostbyname_h
50#define _gethostbyname_h
51
52#if HAVE_GETIPNODEBYNAME
53
54struct ghbnctx
55 {
56 int h_err;
57 struct hostent *hostent;
58 };
59
60#elif HAVE_GETHOSTBYNAME_R == 6
61
62struct ghbnctx
63 {
64 int h_err;
65 struct hostent hostent;
66 char *hostbuf;
67 size_t hostbuf_len;
68 };
69
70#elif HAVE_GETHOSTBYNAME_R == 5
71
72struct ghbnctx
73 {
74 int h_err;
75 struct hostent hostent;
76 char *hostbuf;
77 int hostbuf_len;
78 };
79
80#elif HAVE_GETHOSTBYNAME_R == 3
81
82struct ghbnctx
83 {
84 int h_err;
85 struct hostent_data hostent_data;
86 struct hostent hostent;
87 };
88
89#else
90
91struct ghbnctx
92 {
93 int h_err;
94 };
95
96#endif
97
98struct hostent *gethostbyname_ctx (const char *host, struct ghbnctx *ctx);
99int h_error_ctx (struct ghbnctx *ctx);
100void free_ghbnctx (struct ghbnctx *ctx);
101
102#endif
103
diff --git a/plugins/netutils.c b/plugins/netutils.c
index c0e82da..4234c43 100644
--- a/plugins/netutils.c
+++ b/plugins/netutils.c
@@ -29,22 +29,9 @@
29* 29*
30****************************************************************************/ 30****************************************************************************/
31 31
32#include "config.h" 32#include "netutils.h"
33#include "common.h"
34#include <netinet/in.h>
35#include <arpa/inet.h>
36 33
37extern int socket_timeout; 34int socket_timeout = DEFAULT_SOCKET_TIMEOUT;
38RETSIGTYPE socket_timeout_alarm_handler (int);
39
40int process_tcp_request2 (char *, int, char *, char *, int);
41int process_tcp_request (char *, int, char *, char *, int);
42int process_udp_request (char *, int, char *, char *, int);
43int process_request (char *, int, int, char *, char *, int);
44
45int my_tcp_connect (char *, int, int *);
46int my_udp_connect (char *, int, int *);
47int my_connect (char *, int, int *, int);
48 35
49/* handles socket timeouts */ 36/* handles socket timeouts */
50void 37void
@@ -304,3 +291,69 @@ my_connect (char *host_name, int port, int *sd, int proto)
304 return STATE_CRITICAL; 291 return STATE_CRITICAL;
305 } 292 }
306} 293}
294
295int
296is_host (char *address)
297{
298 if (is_addr (address) || is_hostname (address))
299 return (TRUE);
300
301 return (FALSE);
302}
303
304int
305is_addr (char *address)
306{
307#ifdef USE_IPV6
308 if (is_inet_addr (address) || is_inet6_addr (address))
309#else
310 if (is_inet_addr (address))
311#endif
312 return (TRUE);
313
314 return (FALSE);
315}
316
317int
318resolve_host_or_addr (char *address, int family)
319{
320 struct addrinfo hints;
321 struct addrinfo *res;
322 int retval;
323
324 memset (&hints, 0, sizeof (hints));
325 hints.ai_family = family;
326 retval = getaddrinfo (address, NULL, &hints, &res);
327
328 if (retval != 0)
329 return FALSE;
330 else {
331 freeaddrinfo (res);
332 return TRUE;
333 }
334}
335
336int
337is_inet_addr (char *address)
338{
339 return resolve_host_or_addr (address, AF_INET);
340}
341
342#ifdef USE_IPV6
343int
344is_inet6_addr (char *address)
345{
346 return resolve_host_or_addr (address, AF_INET6);
347}
348#endif
349
350int
351is_hostname (char *s1)
352{
353#ifdef USE_IPV6
354 return resolve_host_or_addr (s1, AF_UNSPEC);
355#else
356 return resolve_host_or_addr (s1, AF_INET);
357#endif
358}
359
diff --git a/plugins/netutils.h b/plugins/netutils.h
index 3ea5166..6c8eed3 100644
--- a/plugins/netutils.h
+++ b/plugins/netutils.h
@@ -43,11 +43,20 @@ int process_tcp_request (char *address, int port, char *sbuffer,
43 char *rbuffer, int rsize); 43 char *rbuffer, int rsize);
44int process_udp_request (char *address, int port, char *sbuffer, 44int process_udp_request (char *address, int port, char *sbuffer,
45 char *rbuffer, int rsize); 45 char *rbuffer, int rsize);
46int process_request (char *address, int port, char *proto, char *sbuffer, 46int process_request (char *address, int port, int proto, char *sbuffer,
47 char *rbuffer, int rsize); 47 char *rbuffer, int rsize);
48 48
49int my_tcp_connect (char *address, int port, int *sd); 49int my_tcp_connect (char *address, int port, int *sd);
50int my_udp_connect (char *address, int port, int *sd); 50int my_udp_connect (char *address, int port, int *sd);
51int my_connect (char *address, int port, int *sd, int proto); 51int my_connect (char *address, int port, int *sd, int proto);
52 52
53int socket_timeout = DEFAULT_SOCKET_TIMEOUT; 53int is_host (char *);
54int is_addr (char *);
55int resolve_host_or_addr (char *, int);
56int is_inet_addr (char *);
57#ifdef USE_IPV6
58int is_inet6_addr (char *);
59#endif
60int is_hostname (char *);
61
62extern int socket_timeout;
diff --git a/plugins/utils.c b/plugins/utils.c
index 7361323..e204e23 100644
--- a/plugins/utils.c
+++ b/plugins/utils.c
@@ -27,15 +27,6 @@ void print_revision (const char *, const char *);
27void terminate (int, const char *fmt, ...); 27void terminate (int, const char *fmt, ...);
28RETSIGTYPE timeout_alarm_handler (int); 28RETSIGTYPE timeout_alarm_handler (int);
29 29
30int is_host (char *);
31int is_addr (char *);
32int resolve_host_or_addr (char *, int);
33int is_inet_addr (char *);
34#ifdef USE_IPV6
35int is_inet6_addr (char *);
36#endif
37int is_hostname (char *);
38
39int is_integer (char *); 30int is_integer (char *);
40int is_intpos (char *); 31int is_intpos (char *);
41int is_intneg (char *); 32int is_intneg (char *);
@@ -171,78 +162,6 @@ timeout_alarm_handler (int signo)
171} 162}
172 163
173int 164int
174is_host (char *address)
175{
176 if (is_addr (address) || is_hostname (address))
177 return (TRUE);
178
179 return (FALSE);
180}
181
182int
183is_addr (char *address)
184{
185#ifdef USE_IPV6
186 if (is_inet_addr (address) || is_inet6_addr (address))
187#else
188 if (is_inet_addr (address))
189#endif
190 return (TRUE);
191
192 return (FALSE);
193}
194
195int
196resolve_host_or_addr (char *address, int family)
197{
198 struct addrinfo hints;
199 struct addrinfo *res;
200 int retval;
201
202 memset (&hints, 0, sizeof (hints));
203 hints.ai_family = family;
204 retval = getaddrinfo (address, NULL, &hints, &res);
205
206 if (retval != 0)
207 return FALSE;
208 else {
209 freeaddrinfo (res);
210 return TRUE;
211 }
212}
213
214int
215is_inet_addr (char *address)
216{
217 return resolve_host_or_addr (address, AF_INET);
218}
219
220#ifdef USE_IPV6
221int
222is_inet6_addr (char *address)
223{
224 return resolve_host_or_addr (address, AF_INET6);
225}
226#endif
227
228/* from RFC-1035
229 *
230 * The labels must follow the rules for ARPANET host names. They must
231 * start with a letter, end with a letter or digit, and have as interior
232 * characters only letters, digits, and hyphen. There are also some
233 * restrictions on the length. Labels must be 63 characters or less. */
234
235int
236is_hostname (char *s1)
237{
238#ifdef USE_IPV6
239 return resolve_host_or_addr (s1, AF_UNSPEC);
240#else
241 return resolve_host_or_addr (s1, AF_INET);
242#endif
243}
244
245int
246is_numeric (char *number) 165is_numeric (char *number)
247{ 166{
248 char tmp[1]; 167 char tmp[1];
diff --git a/plugins/utils.h b/plugins/utils.h
index 89ada6f..43b612c 100644
--- a/plugins/utils.h
+++ b/plugins/utils.h
@@ -27,14 +27,6 @@ int timeout_interval = DEFAULT_SOCKET_TIMEOUT;
27 27
28/* Test input types */ 28/* Test input types */
29 29
30int is_host (char *);
31int is_addr (char *);
32int is_inet_addr (char *);
33#ifdef USE_IPV6
34int is_inet6_addr (char *);
35#endif
36int is_hostname (char *);
37
38int is_integer (char *); 30int is_integer (char *);
39int is_intpos (char *); 31int is_intpos (char *);
40int is_intneg (char *); 32int is_intneg (char *);