summaryrefslogtreecommitdiff
path: root/net-mgmt/netmond/files/patch-ping.c
blob: e593b8c43c98863d9682067174a7b0034e3b411b (plain) (blame)
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
--- ping.c.orig	Fri Aug 22 11:07:53 2003
+++ ping.c	Thu Dec 28 13:31:06 2006
@@ -352,7 +352,8 @@
 	dprintf(("check_netpath(%s)\n", target->name));
 
 	for (nexthop = target->nexthop; nexthop; nexthop = nexthop->next) {
-		if ((nexthop->target && nexthop->target->state != STATE_UP) ||
+		if ((nexthop->target && nexthop->target->state == STATE_UNKNOWN) ||
+		    (nexthop->target && nexthop->target->state == STATE_DOWN) ||
 		    (nexthop->interface && nexthop->interface->state != STATE_UP))
 			return 0;
 	}
@@ -368,6 +369,7 @@
 	u_char buf[MAX_PACKETSZ];
 	struct ip *ip;
 	struct icmp *icmp;
+	struct sockaddr_in *from = (struct sockaddr_in *)&sd->me;
 	struct sockaddr_in *to = (struct sockaddr_in *)&sd->peer;
 	int header_len = sizeof(struct ip);
 	int total_len = method->rport ? method->rport : MIN_PACKETSZ;
@@ -400,7 +402,7 @@
 #endif
 	ip->ip_ttl = IPDEFTTL;
 	ip->ip_p = IPPROTO_ICMP;
-	/* ip->ip_src <-- filled by kernel (hopefulness) */
+	ip->ip_src = from->sin_addr; /* replaced by kernel if=INADDR_ANY (hopefulness) */
 	ip->ip_dst = to->sin_addr;
 
 	if (rr_opt) { /* IP Option: Record Route */
@@ -423,6 +425,7 @@
 	memcpy(icmp->icmp_data, &sd->buf, sizeof(TIMEVAL *));
 
 	icmp->icmp_cksum = in_cksum((u_short *)icmp, total_len - header_len);
+
 #ifdef	NO_ICMP_ERRORS
 	total_len = send(sd->sock, (char *)buf, total_len, 0);
 #else
@@ -600,6 +603,8 @@
 {
 	SESSION *sd = method->sd;
 	int tmpval;
+	char	ipaddr[20];
+	struct	sockaddr_in	*from;
 
 	/* sanity check */
 	if (!sd) return;
@@ -616,6 +621,13 @@
 		echo_reply(errno, sd, 0);
 		return;
 	}
+	/* bind RAW socket to local source address */
+	from = (struct sockaddr_in *)&sd->me;
+	if ( from->sin_addr.s_addr != INADDR_ANY ) {		
+	    if( bind(sd->sock, &sd->me, sizeof(struct sockaddr) ) == -1 ) 
+		report(LOG_WARNING, "echo_start : bind failed for %s: %s",
+		    	intoa(ipaddr,from->sin_addr), strerror(*(__error())) );
+	}
 #ifdef	SO_BSDCOMPAT
 	/* The following option is only necessary on Linux machines because
 	 * they have the unusual behavior of returning some ICMP errors to
@@ -701,7 +713,12 @@
 				if (sd->pkt_recv > 1) msec /= (double)sd->pkt_recv;
 				sprintf(buf, "%g", msec);
 				diag = buf;
-			} else	diag = "0.000";
+			    if ( msec >= 10 ) {
+				sprintf(buf, "%d", (int)msec);
+			    } else {
+				sprintf(buf, "%g", msec);
+			    }
+			} else	diag = "0.0";
 		} else {
 			op = -1;
 			diag = icmp_error(sd->data_int);
@@ -740,8 +757,9 @@
 	METHOD *method;
 {
 	SESSION template;
-	struct sockaddr_in *to;
+	struct sockaddr_in *to, *from;
 	char varname[100];
+	char ipaddr[20];
 
 	dprintf(("echo_init(%s/%s)\n", target->name, method->name));
 
@@ -758,6 +776,9 @@
 	to = (struct sockaddr_in *)&template.peer;
 	to->sin_family = AF_INET;
 	to->sin_addr = method->address ? method->ip_addr : target->ip_addr;
+	from = (struct sockaddr_in *)&template.me;
+	from->sin_family = AF_INET;
+	from->sin_addr = target->ip_srcaddr;
 	template.timeout = method->timeout * 1000000L; /* make microseconds */
 	template.retries = method->retries;
 	template.send = echo_send;
@@ -798,6 +819,7 @@
 	IPPROTO_ICMP,	/* network protocol */
 	0,		/* no packet size for built-in method */
 	0, 0,		/* timeout and retries undefined yet */
+	NULL,NULL,	/* when variables unused */
 	{ 1, 1 },	/* send/expect packet counter */
 
 	/* Non-initialized data */