Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: Add function to get the local mac address (backport #922) #925

Merged
merged 1 commit into from
Nov 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions misc/pcap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1274,3 +1274,56 @@ routethrough (struct in_addr *dest, struct in_addr *source)
return myroutes[best_match].dev->name;
return NULL;
}

/** @brief Given an IP address, determines which interface belongs to.
*
* @param local_ip IP address.
*
* @return Iface name if found, Null otherwise.
*/
char *
get_iface_from_ip (const char *local_ip)
{
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *alldevsp1 = NULL, *devs_aux = NULL;
char *if_name = NULL;

if (pcap_findalldevs (&alldevsp1, errbuf) == -1)
g_debug ("Error for pcap_findalldevs(): %s", errbuf);

devs_aux = alldevsp1;
while (devs_aux)
{
pcap_addr_t *addr_aux = NULL;

addr_aux = devs_aux->addresses;
while (addr_aux)
{
char buffer[INET6_ADDRSTRLEN];

if (((struct sockaddr *) addr_aux->addr)->sa_family == AF_INET)
inet_ntop (AF_INET,
&(((struct sockaddr_in *) addr_aux->addr)->sin_addr),
buffer, INET_ADDRSTRLEN);
else if (((struct sockaddr *) addr_aux->addr)->sa_family == AF_INET6)
inet_ntop (AF_INET6,
&(((struct sockaddr_in6 *) addr_aux->addr)->sin6_addr),
buffer, INET6_ADDRSTRLEN);

if (!g_strcmp0 (buffer, local_ip))
{
if_name = g_strdup (devs_aux->name);
break;
}
addr_aux = addr_aux->next;
}

if (if_name)
break;
devs_aux = devs_aux->next;
}
pcap_freealldevs (alldevsp1);
g_debug ("returning %s as device", if_name);

return if_name;
}
3 changes: 3 additions & 0 deletions misc/pcap_openvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ v6_routethrough (struct in6_addr *, struct in6_addr *);
int
v6_getsourceip (struct in6_addr *, struct in6_addr *);

char *
get_iface_from_ip (const char *);

#endif
61 changes: 60 additions & 1 deletion nasl/nasl_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@
#include <arpa/inet.h> /* for inet_aton */
#include <gvm/base/networking.h>
#include <gvm/util/kb.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netdb.h> /* for gethostbyaddr */
#include <netinet/in.h> /* for in_addr */
#include <string.h> /* for strlen */
#include <unistd.h> /* for gethostname */
#include <sys/ioctl.h>
#include <unistd.h> /* for gethostname */

tree_cell *
get_hostnames (lex_ctxt *lexic)
Expand Down Expand Up @@ -577,3 +580,59 @@ nasl_target_is_ipv6 (lex_ctxt *lexic)

return retc;
}

/**
* @brief Get the MAC address of host
*
* @param[in] lexic Lexical context of NASL interpreter.
* @param[in] ip_address Local IP address
*
* @return The MAC address of the host. NULL otherwise
*/
tree_cell *
nasl_get_local_mac_address_from_ip (lex_ctxt *lexic)
{
tree_cell *retc;
struct ifreq ifr;
int sock;
char *if_name = NULL, *buffer = NULL;
const unsigned char *mac;

char *ip_address = get_str_var_by_num (lexic, 0);

if_name = get_iface_from_ip (ip_address);
if (!if_name)
{
nasl_perror (lexic, "Missing interface name\n");
return NULL;
}

strncpy (ifr.ifr_name, if_name, sizeof (ifr.ifr_name) - 1);
g_free (if_name);
ifr.ifr_name[sizeof (ifr.ifr_name) - 1] = '\0';

sock = socket (PF_INET, SOCK_STREAM, 0);
if (-1 == sock)
{
perror ("socket() ");
return NULL;
}

if (-1 == ioctl (sock, SIOCGIFHWADDR, &ifr))
{
perror ("ioctl(SIOCGIFHWADDR) ");
return NULL;
}

mac = (unsigned char *) ifr.ifr_hwaddr.sa_data;
buffer = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1],
mac[2], mac[3], mac[4], mac[5]);

close (sock);

retc = alloc_typed_cell (CONST_DATA);
retc->x.str_val = buffer;
retc->size = 17;

return retc;
}
3 changes: 3 additions & 0 deletions nasl/nasl_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,7 @@ nasl_same_host (lex_ctxt *);
tree_cell *
nasl_target_is_ipv6 (lex_ctxt *lexic);

tree_cell *
nasl_get_local_mac_address_from_ip (lex_ctxt *);

#endif
1 change: 1 addition & 0 deletions nasl/nasl_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ static init_func libfuncs[] = {
{"resolve_host_name", resolve_hostname},
{"resolve_hostname_to_multiple_ips", resolve_hostname_to_multiple_ips},
{"get_host_ip", get_host_ip},
{"get_local_mac_address_from_ip", nasl_get_local_mac_address_from_ip},
{"same_host", nasl_same_host},
{"TARGET_IS_IPV6", nasl_target_is_ipv6},
{"get_host_open_port", get_host_open_port},
Expand Down