liboping
liboping copied to clipboard
How do I get the address of the host from which the ICMP packet came?
In liboping, it is possible to set PING_OPT_TTL and get PING_INFO_RECV_TTL and PING_INFO_RECV_QOS, but how to get PING_INFO_RECV HOST_ADDRESS for trace route???
to get the address of the dropped ICMP packet, I have made such modifications to your library
diff --git a/src/liboping.c b/src/liboping.c
index bf9e059..0ebbc81 100644
--- a/src/liboping.c
+++ b/src/liboping.c
@@ -128,6 +128,7 @@ struct pinghost
struct pinghost *next;
struct pinghost *table_next;
+ struct in_addr recv_addr;
};
struct pingobj
@@ -307,7 +308,7 @@ static pinghost_t *ping_receive_ipv4 (pingobj_t *obj, char *buffer,
return (NULL);
icmp_hdr = (struct icmp *) buffer;
- if (icmp_hdr->icmp_type != ICMP_ECHOREPLY)
+ if (icmp_hdr->icmp_type != ICMP_ECHOREPLY && icmp_hdr->icmp_type != ICMP_TIME_EXCEEDED)
{
dprintf ("Unexpected ICMP type: %"PRIu8"\n", icmp_hdr->icmp_type);
return (NULL);
@@ -329,6 +330,9 @@ static pinghost_t *ping_receive_ipv4 (pingobj_t *obj, char *buffer,
ident = ntohs (icmp_hdr->icmp_id);
seq = ntohs (icmp_hdr->icmp_seq);
+ if (icmp_hdr->icmp_type == ICMP_TIME_EXCEEDED)
+ ptr = obj->head;
+ else
for (ptr = obj->table[ident % PING_TABLE_LEN];
ptr != NULL; ptr = ptr->table_next)
{
@@ -468,15 +472,18 @@ static int ping_receive_one (pingobj_t *obj, struct timeval *now, int addrfam)
ssize_t payload_buffer_len;
char control_buffer[4096];
struct iovec payload_iovec;
+ struct sockaddr_in recv_sin;
memset (&payload_iovec, 0, sizeof (payload_iovec));
payload_iovec.iov_base = payload_buffer;
payload_iovec.iov_len = sizeof (payload_buffer);
memset (&msghdr, 0, sizeof (msghdr));
- /* unspecified source address */
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
+// /* unspecified source address */
+// msghdr.msg_name = NULL;
+// msghdr.msg_namelen = 0;
+ msghdr.msg_name = &recv_sin;
+ msghdr.msg_namelen = sizeof(recv_sin);
/* output buffer vector, see readv(2) */
msghdr.msg_iov = &payload_iovec;
msghdr.msg_iovlen = 1;
@@ -634,6 +641,8 @@ static int ping_receive_one (pingobj_t *obj, struct timeval *now, int addrfam)
timerclear (host->timer);
+ host->recv_addr = recv_sin.sin_addr;
+
return (0);
}
@@ -1933,6 +1942,15 @@ int ping_iterator_get_info (pingobj_iter_t *iter, int info,
memcpy(buffer,&iter->recv_qos,*buffer_len);
ret = 0;
break;
+
+ case PING_INFO_RECV_ADDR:
+ ret = ENOMEM;
+ *buffer_len = sizeof (struct in_addr);
+ if (orig_buffer_len < *buffer_len)
+ break;
+ *((struct in_addr *) buffer) = iter->recv_addr;
+ ret = 0;
+ break;
}
return (ret);
diff --git a/src/oping.h b/src/oping.h
index ff144e8..58e8e19 100644
--- a/src/oping.h
+++ b/src/oping.h
@@ -88,6 +88,8 @@ int ping_iterator_count (pingobj_t *obj);
#define PING_INFO_DROPPED 9
#define PING_INFO_RECV_TTL 10
#define PING_INFO_RECV_QOS 11
+#define PING_INFO_RECV_ADDR 12
+
int ping_iterator_get_info (pingobj_iter_t *iter, int info,
void *buffer, size_t *buffer_len);