diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2021-03-04 23:03:34 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2021-03-04 23:03:34 +0000 |
commit | 8dc8d72ae73ecde10c2ed933c2322056c907c4b4 (patch) | |
tree | dcb101fb00b793701feedf34738c8e6db0663154 | |
parent | 77098b8eef357426d46b0b718f5ca8c09a62695e (diff) | |
parent | 6a0176df1e0ed17868528e2745bfda246fbbfcce (diff) | |
download | slirp-8dc8d72ae73ecde10c2ed933c2322056c907c4b4.zip slirp-8dc8d72ae73ecde10c2ed933c2322056c907c4b4.tar.gz slirp-8dc8d72ae73ecde10c2ed933c2322056c907c4b4.tar.bz2 |
Merge branch 'neighbor-info' into 'master'
Neighbor info
See merge request slirp/libslirp!71
-rw-r--r-- | src/arp_table.c | 12 | ||||
-rw-r--r-- | src/libslirp.h | 3 | ||||
-rw-r--r-- | src/libslirp.map | 1 | ||||
-rw-r--r-- | src/misc.c | 44 | ||||
-rw-r--r-- | src/ndp_table.c | 18 | ||||
-rw-r--r-- | src/slirp.c | 11 | ||||
-rw-r--r-- | src/slirp.h | 6 | ||||
-rw-r--r-- | src/util.c | 11 | ||||
-rw-r--r-- | src/util.h | 8 |
9 files changed, 91 insertions, 23 deletions
diff --git a/src/arp_table.c b/src/arp_table.c index 959e5b9..ba8c8a4 100644 --- a/src/arp_table.c +++ b/src/arp_table.c @@ -34,11 +34,12 @@ void arp_table_add(Slirp *slirp, uint32_t ip_addr, ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr; ArpTable *arptbl = &slirp->arp_table; int i; + char ethaddr_str[ETH_ADDRSTRLEN]; DEBUG_CALL("arp_table_add"); DEBUG_ARG("ip = %s", inet_ntoa((struct in_addr){ .s_addr = ip_addr })); - DEBUG_ARG("hw addr = %02x:%02x:%02x:%02x:%02x:%02x", ethaddr[0], ethaddr[1], - ethaddr[2], ethaddr[3], ethaddr[4], ethaddr[5]); + DEBUG_ARG("hw addr = %s", slirp_ether_ntoa(ethaddr, ethaddr_str, + sizeof(ethaddr_str))); if (ip_addr == 0 || ip_addr == 0xffffffff || ip_addr == broadcast_addr) { /* Do not register broadcast addresses */ @@ -67,6 +68,7 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr, ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr; ArpTable *arptbl = &slirp->arp_table; int i; + char ethaddr_str[ETH_ADDRSTRLEN]; DEBUG_CALL("arp_table_search"); DEBUG_ARG("ip = %s", inet_ntoa((struct in_addr){ .s_addr = ip_addr })); @@ -81,9 +83,9 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr, for (i = 0; i < ARP_TABLE_SIZE; i++) { if (arptbl->table[i].ar_sip == ip_addr) { memcpy(out_ethaddr, arptbl->table[i].ar_sha, ETH_ALEN); - DEBUG_ARG("found hw addr = %02x:%02x:%02x:%02x:%02x:%02x", - out_ethaddr[0], out_ethaddr[1], out_ethaddr[2], - out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]); + DEBUG_ARG("found hw addr = %s", + slirp_ether_ntoa(out_ethaddr, ethaddr_str, + sizeof(ethaddr_str))); return 1; } } diff --git a/src/libslirp.h b/src/libslirp.h index 4afb7d6..b52b63d 100644 --- a/src/libslirp.h +++ b/src/libslirp.h @@ -205,6 +205,9 @@ int slirp_remove_guestfwd(Slirp *slirp, struct in_addr guest_addr, /* Return a human-readable state of the slirp stack */ char *slirp_connection_info(Slirp *slirp); +/* Return a human-readable state of the NDP/ARP tables */ +char *slirp_neighbor_info(Slirp *slirp); + /* Save the slirp state through the write_cb. The opaque pointer is passed as * such to the write_cb. */ void slirp_state_save(Slirp *s, SlirpWriteCb write_cb, void *opaque); diff --git a/src/libslirp.map b/src/libslirp.map index c0113c9..20a17ac 100644 --- a/src/libslirp.map +++ b/src/libslirp.map @@ -32,4 +32,5 @@ SLIRP_4.2 { SLIRP_4.5 { slirp_add_ipv6_hostfwd; slirp_remove_ipv6_hostfwd; + slirp_neighbor_info; } SLIRP_4.2; @@ -377,6 +377,48 @@ char *slirp_connection_info(Slirp *slirp) return g_string_free(str, FALSE); } +char *slirp_neighbor_info(Slirp *slirp) +{ + GString *str = g_string_new(NULL); + ArpTable *arp_table = &slirp->arp_table; + NdpTable *ndp_table = &slirp->ndp_table; + char ip_addr[INET6_ADDRSTRLEN]; + char eth_addr[ETH_ADDRSTRLEN]; + const char *ip; + + g_string_append_printf(str, " %5s %-17s %s\n", + "Table", "MacAddr", "IP Address"); + + for (int i = 0; i < ARP_TABLE_SIZE; ++i) { + struct in_addr addr; + addr.s_addr = arp_table->table[i].ar_sip; + if (!addr.s_addr) { + continue; + } + ip = inet_ntop(AF_INET, &addr, ip_addr, sizeof(ip_addr)); + g_assert(ip != NULL); + g_string_append_printf(str, " %5s %-17s %s\n", "ARP", + slirp_ether_ntoa(arp_table->table[i].ar_sha, + eth_addr, sizeof(eth_addr)), + ip); + } + + for (int i = 0; i < NDP_TABLE_SIZE; ++i) { + if (in6_zero(&ndp_table->table[i].ip_addr)) { + continue; + } + ip = inet_ntop(AF_INET6, &ndp_table->table[i].ip_addr, ip_addr, + sizeof(ip_addr)); + g_assert(ip != NULL); + g_string_append_printf(str, " %5s %-17s %s\n", "NDP", + slirp_ether_ntoa(ndp_table->table[i].eth_addr, + eth_addr, sizeof(eth_addr)), + ip); + } + + return g_string_free(str, FALSE); +} + int slirp_bind_outbound(struct socket *so, unsigned short af) { int ret = 0; @@ -395,4 +437,4 @@ int slirp_bind_outbound(struct socket *so, unsigned short af) ret = bind(so->s, addr, addr_size); } return ret; -}
\ No newline at end of file +} diff --git a/src/ndp_table.c b/src/ndp_table.c index 110d6ea..61ae8e0 100644 --- a/src/ndp_table.c +++ b/src/ndp_table.c @@ -12,13 +12,14 @@ void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr, char addrstr[INET6_ADDRSTRLEN]; NdpTable *ndp_table = &slirp->ndp_table; int i; + char ethaddr_str[ETH_ADDRSTRLEN]; inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN); DEBUG_CALL("ndp_table_add"); DEBUG_ARG("ip = %s", addrstr); - DEBUG_ARG("hw addr = %02x:%02x:%02x:%02x:%02x:%02x", ethaddr[0], ethaddr[1], - ethaddr[2], ethaddr[3], ethaddr[4], ethaddr[5]); + DEBUG_ARG("hw addr = %s", slirp_ether_ntoa(ethaddr, ethaddr_str, + sizeof(ethaddr_str))); if (IN6_IS_ADDR_MULTICAST(&ip_addr) || in6_zero(&ip_addr)) { /* Do not register multicast or unspecified addresses */ @@ -50,6 +51,7 @@ bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr, char addrstr[INET6_ADDRSTRLEN]; NdpTable *ndp_table = &slirp->ndp_table; int i; + char ethaddr_str[ETH_ADDRSTRLEN]; inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN); @@ -66,18 +68,18 @@ bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr, out_ethaddr[3] = ip_addr.s6_addr[13]; out_ethaddr[4] = ip_addr.s6_addr[14]; out_ethaddr[5] = ip_addr.s6_addr[15]; - DEBUG_ARG("multicast addr = %02x:%02x:%02x:%02x:%02x:%02x", - out_ethaddr[0], out_ethaddr[1], out_ethaddr[2], - out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]); + DEBUG_ARG("multicast addr = %s", + slirp_ether_ntoa(out_ethaddr, ethaddr_str, + sizeof(ethaddr_str))); return 1; } for (i = 0; i < NDP_TABLE_SIZE; i++) { if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) { memcpy(out_ethaddr, ndp_table->table[i].eth_addr, ETH_ALEN); - DEBUG_ARG("found hw addr = %02x:%02x:%02x:%02x:%02x:%02x", - out_ethaddr[0], out_ethaddr[1], out_ethaddr[2], - out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]); + DEBUG_ARG("found hw addr = %s", + slirp_ether_ntoa(out_ethaddr, ethaddr_str, + sizeof(ethaddr_str))); return 1; } } diff --git a/src/slirp.c b/src/slirp.c index 79ba734..110e6fc 100644 --- a/src/slirp.c +++ b/src/slirp.c @@ -1060,6 +1060,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm) uint8_t ethaddr[ETH_ALEN]; const struct ip *iph = (const struct ip *)ifm->m_data; int ret; + char ethaddr_str[ETH_ADDRSTRLEN]; if (ifm->m_len + ETH_HLEN > sizeof(buf)) { return 1; @@ -1085,12 +1086,10 @@ int if_encap(Slirp *slirp, struct mbuf *ifm) } memcpy(eh->h_dest, ethaddr, ETH_ALEN); - DEBUG_ARG("src = %02x:%02x:%02x:%02x:%02x:%02x", eh->h_source[0], - eh->h_source[1], eh->h_source[2], eh->h_source[3], - eh->h_source[4], eh->h_source[5]); - DEBUG_ARG("dst = %02x:%02x:%02x:%02x:%02x:%02x", eh->h_dest[0], - eh->h_dest[1], eh->h_dest[2], eh->h_dest[3], eh->h_dest[4], - eh->h_dest[5]); + DEBUG_ARG("src = %s", slirp_ether_ntoa(eh->h_source, ethaddr_str, + sizeof(ethaddr_str))); + DEBUG_ARG("dst = %s", slirp_ether_ntoa(eh->h_dest, ethaddr_str, + sizeof(ethaddr_str))); memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len); slirp_send_packet_all(slirp, buf, ifm->m_len + ETH_HLEN); return 1; diff --git a/src/slirp.h b/src/slirp.h index 4f8b133..80f6ac6 100644 --- a/src/slirp.h +++ b/src/slirp.h @@ -85,9 +85,9 @@ struct slirp_arphdr { /* * Ethernet looks like this : This bit is variable sized however... */ - unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ + uint8_t ar_sha[ETH_ALEN]; /* sender hardware address */ uint32_t ar_sip; /* sender IP address */ - unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ + uint8_t ar_tha[ETH_ALEN]; /* target hardware address */ uint32_t ar_tip; /* target IP address */ } SLIRP_PACKED; @@ -105,7 +105,7 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr, uint8_t out_ethaddr[ETH_ALEN]); struct ndpentry { - unsigned char eth_addr[ETH_ALEN]; /* sender hardware address */ + uint8_t eth_addr[ETH_ALEN]; /* sender hardware address */ struct in6_addr ip_addr; /* sender IP address */ }; @@ -427,3 +427,14 @@ int slirp_fmt0(char *str, size_t size, const char *format, ...) return rv; } + +const char *slirp_ether_ntoa(const uint8_t *addr, char *out_str, + size_t out_str_size) +{ + assert(out_str_size >= ETH_ADDRSTRLEN); + + slirp_fmt0(out_str, out_str_size, "%02x:%02x:%02x:%02x:%02x:%02x", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + + return out_str; +} @@ -84,6 +84,7 @@ struct iovec { #define SCALE_MS 1000000 #define ETH_ALEN 6 +#define ETH_ADDRSTRLEN 18 /* "xx:xx:xx:xx:xx:xx", with trailing NUL */ #define ETH_HLEN 14 #define ETH_P_IP (0x0800) /* Internet Protocol packet */ #define ETH_P_ARP (0x0806) /* Address Resolution packet */ @@ -186,4 +187,11 @@ void slirp_pstrcpy(char *buf, int buf_size, const char *str); int slirp_fmt(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4); int slirp_fmt0(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4); +/* + * Pretty print a MAC address into out_str. + * As a convenience returns out_str. + */ +const char *slirp_ether_ntoa(const uint8_t *addr, char *out_str, + size_t out_str_len); + #endif |