liboping icon indicating copy to clipboard operation
liboping copied to clipboard

How do I get the address of the host from which the ICMP packet came?

Open wolverin-a opened this issue 2 years ago • 1 comments

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???

wolverin-a avatar Jul 09 '23 04:07 wolverin-a

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);

wolverin-a avatar Jul 10 '23 03:07 wolverin-a