aboutsummaryrefslogtreecommitdiff
path: root/eperd/ping.c
diff options
context:
space:
mode:
Diffstat (limited to 'eperd/ping.c')
-rw-r--r--eperd/ping.c69
1 files changed, 54 insertions, 15 deletions
diff --git a/eperd/ping.c b/eperd/ping.c
index 4d17317..834b9dc 100644
--- a/eperd/ping.c
+++ b/eperd/ping.c
@@ -66,6 +66,12 @@ enum
/* Definition for various types of counters */
typedef uint64_t counter_t;
+/* For matching up requests and replies. Assume that 64 bits is enough */
+struct cookie
+{
+ uint8_t data[8];
+};
+
/* How to keep track of a PING session */
struct pingbase
{
@@ -116,6 +122,7 @@ struct pingstate
size_t resmax;
struct pingbase *base;
+ struct cookie cookie;
sa_family_t af; /* Desired address family */
struct evutil_addrinfo *dns_res;
@@ -153,6 +160,7 @@ struct pingstate
struct evdata {
struct timeval ts;
uint32_t index;
+ struct cookie cookie;
};
@@ -209,13 +217,15 @@ static void report(struct pingstate *state)
fprintf(fh, DBQ(dst_name) ":" DBQ(%s),
state->hostname);
+ fprintf(fh, ", " DBQ(af) ":%d",
+ state->af == AF_INET ? 4 : 6);
+
if (!state->no_dst)
{
getnameinfo((struct sockaddr *)&state->sin6, state->socklen,
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
- fprintf(fh, ", " DBQ(dst_addr) ":" DBQ(%s) ", " DBQ(af) ":%d",
- namebuf, state->sin6.sin6_family == AF_INET6 ? 6 : 4);
+ fprintf(fh, ", " DBQ(dst_addr) ":" DBQ(%s), namebuf);
}
if (state->got_reply)
@@ -302,7 +312,6 @@ static void ping_cb(int result, int bytes, int psize,
"%s{ ", pingstate->first ? "" : ", ");
add_str(pingstate, line);
pingstate->first= 0;
- pingstate->no_dst= 0;
if (result == PING_ERR_DUP)
{
add_str(pingstate, DBQ(dup) ":1, ");
@@ -373,7 +382,6 @@ static void ping_cb(int result, int bytes, int psize,
"%s{ " DBQ(x) ":" DBQ(*),
pingstate->first ? "" : ", ");
add_str(pingstate, line);
- pingstate->no_dst= 0;
}
if (result == PING_ERR_SENDTO)
{
@@ -381,7 +389,6 @@ static void ping_cb(int result, int bytes, int psize,
"%s{ " DBQ(error) ":" DBQ(sendto failed: %s),
pingstate->first ? "" : ", ", strerror(seq));
add_str(pingstate, line);
- pingstate->no_dst= 0;
}
if (result == PING_ERR_TIMEOUT || result == PING_ERR_SENDTO)
{
@@ -463,7 +470,7 @@ static int mkcksum(u_short *p, int n)
* ho hosts being monitored
*/
static void fmticmp4(u_char *buffer, size_t *sizep, u_int8_t seq,
- uint32_t idx, pid_t pid)
+ uint32_t idx, pid_t pid, struct cookie *cookiep)
{
size_t minlen;
struct icmp *icmp = (struct icmp *) buffer;
@@ -477,8 +484,7 @@ static void fmticmp4(u_char *buffer, size_t *sizep, u_int8_t seq,
if (*sizep > MAX_DATA_SIZE - ICMP_MINLEN)
*sizep= MAX_DATA_SIZE - ICMP_MINLEN;
- if (*sizep > minlen)
- memset(buffer+minlen, '\0', *sizep-minlen);
+ memset(buffer, '\0', *sizep + ICMP_MINLEN);
/* The ICMP header (no checksum here until user data has been filled in) */
icmp->icmp_type = ICMP_ECHO; /* type of message */
@@ -490,6 +496,7 @@ static void fmticmp4(u_char *buffer, size_t *sizep, u_int8_t seq,
gettimeofday(&now, NULL);
data->ts = now; /* current time */
data->index = idx; /* index into an array */
+ data->cookie= *cookiep;
/* Last, compute ICMP checksum */
icmp->icmp_cksum = 0;
@@ -513,7 +520,7 @@ static void fmticmp4(u_char *buffer, size_t *sizep, u_int8_t seq,
* ho hosts being monitored
*/
static void fmticmp6(u_char *buffer, size_t *sizep,
- u_int8_t seq, uint32_t idx, pid_t pid)
+ u_int8_t seq, uint32_t idx, pid_t pid, struct cookie *cookiep)
{
size_t minlen;
struct icmp6_hdr *icmp = (struct icmp6_hdr *) buffer;
@@ -527,8 +534,7 @@ static void fmticmp6(u_char *buffer, size_t *sizep,
if (*sizep > MAX_DATA_SIZE - ICMP6_HDRSIZE)
*sizep= MAX_DATA_SIZE - ICMP6_HDRSIZE;
- if (*sizep > minlen)
- memset(buffer+minlen, '\0', *sizep-minlen);
+ memset(buffer, '\0', *sizep+ICMP6_HDRSIZE);
/* The ICMP header (no checksum here until user data has been filled in) */
icmp->icmp6_type = ICMP6_ECHO_REQUEST; /* type of message */
@@ -540,6 +546,7 @@ static void fmticmp6(u_char *buffer, size_t *sizep,
gettimeofday(&now, NULL);
data->ts = now; /* current time */
data->index = idx; /* index into an array */
+ data->cookie= *cookiep;
icmp->icmp6_cksum = 0;
}
@@ -577,7 +584,7 @@ static void ping_xmit(struct pingstate *host)
{
/* Format the ICMP Echo Reply packet to send */
fmticmp6(base->packet, &host->cursize, host->seq, host->index,
- base->pid);
+ base->pid, &host->cookie);
host->loc_socklen= sizeof(host->loc_sin6);
getsockname(host->socket, &host->loc_sin6, &host->loc_socklen);
@@ -592,7 +599,7 @@ static void ping_xmit(struct pingstate *host)
{
/* Format the ICMP Echo Reply packet to send */
fmticmp4(base->packet, &host->cursize, host->seq, host->index,
- base->pid);
+ base->pid, &host->cookie);
host->loc_socklen= sizeof(host->loc_sin6);
getsockname(host->socket, &host->loc_sin6, &host->loc_socklen);
@@ -735,6 +742,13 @@ printf("ready_callback4: too short\n");
if (state != base->table[data->index])
goto done; /* Not for us */
+ /* Make sure we got the right cookie */
+ if (memcmp(&state->cookie, &data->cookie, sizeof(state->cookie)) != 0)
+ {
+ crondlog(LVL8 "ICMP with wrong cookie");
+ goto done;
+ }
+
/* Check for Destination Host Unreachable */
if (icmp->type == ICMP_ECHO)
{
@@ -802,7 +816,7 @@ static void ready_callback6 (int __attribute((unused)) unused,
struct pingstate *state;
int nrecv, isDup;
- struct sockaddr_in remote; /* responding internet address */
+ struct sockaddr_in6 remote; /* responding internet address */
struct icmp6_hdr *icmp;
struct evdata * data;
@@ -862,6 +876,13 @@ static void ready_callback6 (int __attribute((unused)) unused,
if (state != base->table[data->index])
goto done; /* Not for us */
+ /* Make sure we got the right cookie */
+ if (memcmp(&state->cookie, &data->cookie, sizeof(state->cookie)) != 0)
+ {
+ crondlog(LVL8 "ICMP with wrong cookie");
+ goto done;
+ }
+
/* Check for Destination Host Unreachable */
if (icmp->icmp6_type == ICMP6_ECHO_REPLY)
{
@@ -925,7 +946,7 @@ static void *ping_init(int __attribute((unused)) argc, char *argv[],
{
static struct pingbase *ping_base;
- int i, newsiz, delay_name_res;
+ int i, r, fd, newsiz, delay_name_res;
uint32_t opt;
unsigned pingcount; /* must be int-sized */
unsigned size, interval;
@@ -937,6 +958,7 @@ static void *ping_init(int __attribute((unused)) argc, char *argv[],
struct pingstate *state;
len_and_sockaddr *lsa;
FILE *fh;
+ struct cookie cookie;
if (!ping_base)
{
@@ -957,6 +979,21 @@ static void *ping_init(int __attribute((unused)) argc, char *argv[],
ping_base->done= 0;
}
+ /* Get cookie */
+ fd= open("/dev/urandom", O_RDONLY);
+ if (fd == -1)
+ {
+ crondlog(LVL8 "unable to open /dev/urandom");
+ return NULL;
+ }
+ r= read(fd, &cookie, sizeof(cookie));
+ close(fd);
+ if (r != sizeof(cookie))
+ {
+ crondlog(LVL8 "unable to read from /dev/urandom");
+ return NULL;
+ }
+
/* Parse arguments */
pingcount= 3;
size= 0;
@@ -1080,6 +1117,7 @@ static void *ping_init(int __attribute((unused)) argc, char *argv[],
state->result= NULL;
state->reslen= 0;
state->resmax= 0;
+ state->cookie= cookie;
state->maxsize = size;
state->base->done= done;
@@ -1100,6 +1138,7 @@ static void ping_start2(void *state)
pingstate->send_error= 0;
pingstate->got_reply= 0;
+ pingstate->no_dst= 0;
if (pingstate->af == AF_INET)
{