Package: monit
Version: 5.0.3-1
Severity: important
Tags: patch

Because monit uses gethostbyname() in net.c, it tries to interpret the mapped
addresses it gets (::ffff:192.168.1.1) as AF_INET and thus connects to 0.0.0.0,
which works by chance for some services, but not for all.

This is easily fixed by using getaddrinfo() (which is also beneficial for
supporting IPv6 and for other reasons, see:
 http://udrepper.livejournal.com/16116.html
). Patch is attached.

-- System Information:
Debian Release: squeeze/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.30-midna (SMP w/2 CPU cores)
Locale: LANG=C, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
>From 5ef3994a4a8464ed7af121504ed0153fa7ac2d64 Mon Sep 17 00:00:00 2001
From: Michael Stapelberg <mich...@stapelberg.de>
Date: Tue, 11 Aug 2009 23:49:36 +0200
Subject: [PATCH] Use getaddrinfo() instead of gethostbyname() to work with "options inet6" in /etc/resolv.conf

---
 net.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/net.c b/net.c
index 8aed7e4..4bc7dd7 100644
--- a/net.c
+++ b/net.c
@@ -229,16 +229,21 @@ int check_udp_socket(int socket) {
 int create_socket(const char *hostname, int port, int type, int timeout) {
 
   int s;
-  struct hostent *hp;
+  int err;
   struct sockaddr_in sin;
+  struct sockaddr_in *sa;
+  struct addrinfo hints;
+  struct addrinfo *result;
   
   ASSERT(hostname);
 
-  if((hp= gethostbyname(hostname)) == NULL) {
+  memset(&hints, 0, sizeof(struct addrinfo));
+  hints.ai_family = AF_INET;
+  if((err= getaddrinfo(hostname, NULL, &hints, &result)) != 0) {
     return -1;
   }
 
-  endhostent();
+  sa = (struct sockaddr_in *)result->ai_addr;
   
   if((s= socket(AF_INET, type, 0)) < 0) {
     return -1;
@@ -246,7 +251,7 @@ int create_socket(const char *hostname, int port, int type, int timeout) {
 
   sin.sin_family= AF_INET;
   sin.sin_port= htons(port);
-  memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
+  memcpy(&sin.sin_addr, &(sa->sin_addr), result->ai_addrlen);
   
   if(! set_noblock(s)) {
     goto error;
-- 
1.6.3.1

Reply via email to