summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorJeremy T. Bouse <undrgrid@users.sourceforge.net>2003-03-15 01:25:35 (GMT)
committerJeremy T. Bouse <undrgrid@users.sourceforge.net>2003-03-15 01:25:35 (GMT)
commit11b35b92e3195d230bef359f6a0679ae4414716b (patch)
treef4911e5804c1f3037dcf63bbbf0b823c5ac19e5f /plugins
parent6cf5fc3c74c0bdfef6c4cc1b627578378ad3a407 (diff)
downloadmonitoring-plugins-11b35b92e3195d230bef359f6a0679ae4414716b.tar.gz
Spent the day working on backwards compatability using getaddrinfo()
Moved getaddrinfo.? and gethostbyname.? from lib/ to plugins/ due to problems with compiling into the libnagiosplug.a as it required linking against socket libraries which are unneeded except for network based plugins. This code should hopefully happily work for all systems and has been tested prior to commit on Debian GNU/Linux, SPARC Solaris 7 and SPARC Solaris 9. git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@424 f882894a-f735-0410-b71e-b25c423dba1c
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 *);