summaryrefslogtreecommitdiffstats
path: root/web/attachments/264034-nagios-plugins_bind.patch
blob: 208ae9612394b6abae01d010ce29d1aaebf61acd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
diff -ur nagiosplug-trunk/plugins/check_http.c nagiosplug/plugins/check_http.c
--- nagiosplug-trunk/plugins/check_http.c	2008-01-28 16:20:49.000000000 +0100
+++ nagiosplug/plugins/check_http.c	2008-01-28 17:03:51.000000000 +0100
@@ -97,6 +97,7 @@
 char server_port_text[6] = "";
 char server_type[6] = "http";
 char *server_address;
+char *client_address = NULL;
 char *host_name;
 char *server_url;
 char *user_agent;
@@ -188,6 +189,7 @@
     {"ssl", no_argument, 0, 'S'},
     {"post", required_argument, 0, 'P'},
     {"IP-address", required_argument, 0, 'I'},
+    {"bind-address", required_argument, 0, 'B'},
     {"url", required_argument, 0, 'u'},
     {"port", required_argument, 0, 'p'},
     {"authorization", required_argument, 0, 'a'},
@@ -228,7 +230,7 @@
   }
 
   while (1) {
-    c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:T:I:a:e:p:s:R:r:u:f:C:nlLSm:M:N", longopts, &option);
+    c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:T:I:B:a:e:p:s:R:r:u:f:C:nlLSm:M:N", longopts, &option);
     if (c == -1 || c == EOF)
       break;
 
@@ -328,6 +330,9 @@
     case 'I': /* Server IP-address */
       server_address = strdup (optarg);
       break;
+    case 'B': /* Bind address */
+      client_address = strdup (optarg);
+      break;
     case 'u': /* URL path */
       server_url = strdup (optarg);
       server_url_length = strlen (server_url);
@@ -732,7 +737,7 @@
   int result = STATE_UNKNOWN;
 
   /* try to connect to the host at the given port number */
-  if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK)
+  if (my_tcp_bind_connect (server_address, server_port, &sd, client_address) != STATE_OK)
     die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n"));
 #ifdef HAVE_SSL
   if (use_ssl == TRUE) {
@@ -1241,6 +1246,9 @@
   printf ("    %s\n", _("Append a port to include it in the header (eg: example.com:5000)"));
   printf (" %s\n", "-I, --IP-address=ADDRESS");
   printf ("    %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup)."));
+  printf (" %s\n", "-B, --bind-address=ADDRESS");
+  printf ("    %s\n", _("IP address or name on the local machine to be used as the source address"));
+  printf ("    %s\n", _("of the connection."));
   printf (" %s\n", "-p, --port=INTEGER");
   printf (" %s", _("Port number (default: "));
   printf ("%d)\n", HTTP_PORT);
diff -ur nagiosplug-trunk/plugins/netutils.c nagiosplug/plugins/netutils.c
--- nagiosplug-trunk/plugins/netutils.c	2008-01-28 16:20:49.000000000 +0100
+++ nagiosplug/plugins/netutils.c	2008-01-28 17:33:48.000000000 +0100
@@ -163,12 +163,14 @@
 
 /* opens a tcp or udp connection to a remote host or local socket */
 int
-np_net_connect (const char *host_name, int port, int *sd, int proto)
+np_net_connect (const char *host_name, int port, int *sd, int proto, ...)
 {
+	va_list ap;
 	struct addrinfo hints;
-	struct addrinfo *r, *res;
+	struct addrinfo *r, *res, *rb;
 	struct sockaddr_un su;
 	char port_str[6], host[MAX_HOST_ADDRESS_LENGTH];
+	char *bindaddress;
 	size_t len;
 	int socktype, result;
 
@@ -200,6 +202,28 @@
 		}
 
 		r = res;
+
+		va_start(ap, proto);
+		bindaddress = va_arg(ap, char *);
+		va_end(ap);
+		if (bindaddress) {
+			memset (&hints, 0, sizeof (hints));
+			hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
+			hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
+			hints.ai_flags = AI_PASSIVE;    /* For wildcard IP address */
+			hints.ai_protocol = 0;          /* Any protocol */
+			hints.ai_canonname = NULL;
+			hints.ai_addr = NULL;
+			hints.ai_next = NULL;
+			
+			result = getaddrinfo (bindaddress, NULL, &hints, &res);
+			if (result != 0) {
+				printf ("%s\n", gai_strerror (result));
+				return STATE_UNKNOWN;
+			}
+			rb = res;
+		}
+
 		while (r) {
 			/* attempt to create a socket */
 			*sd = socket (r->ai_family, socktype, r->ai_protocol);
@@ -210,6 +234,15 @@
 				return STATE_UNKNOWN;
 			}
 
+			/* attempt to bind to source IP */
+			if (bindaddress) {
+				result = bind(*sd, rb->ai_addr, rb->ai_addrlen);
+				if (result != 0) {
+					printf ("%s\n", _("Unable to bind to source address"));
+					return STATE_UNKNOWN;
+				}
+			}
+
 			/* attempt to open a connection */
 			result = connect (*sd, r->ai_addr, r->ai_addrlen);
 
diff -ur nagiosplug-trunk/plugins/netutils.h nagiosplug/plugins/netutils.h
--- nagiosplug-trunk/plugins/netutils.h	2008-01-28 16:20:49.000000000 +0100
+++ nagiosplug/plugins/netutils.h	2008-01-28 17:27:30.000000000 +0100
@@ -64,7 +64,10 @@
 /* my_connect and wrapper macros */
 #define my_tcp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_TCP)
 #define my_udp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_UDP)
-int np_net_connect(const char *address, int port, int *sd, int proto);
+#define my_tcp_bind_connect(addr, port, s, bind_addr) np_net_connect(addr, port, s, IPPROTO_TCP, bind_addr)
+#define my_ucp_bind_connect(addr, port, s, bind_addr) np_net_connect(addr, port, s, IPPROTO_TCP, bind_addr)
+
+int np_net_connect(const char *address, int port, int *sd, int proto, ...);
 
 /* send_request and wrapper macros */
 #define send_tcp_request(s, sbuf, rbuf, rsize) \