Functions to forge and manipulate datalink layer frames.
More...
#include "nasl_frame_forgery.h"
#include "../misc/bpf_share.h"
#include "../misc/pcap_openvas.h"
#include "../misc/plugutils.h"
#include "capture_packet.h"
#include "nasl_debug.h"
#include <errno.h>
#include <gvm/base/networking.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/ether.h>
#include <netinet/if_ether.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
Go to the source code of this file.
|
| struct pseudo_eth_arp | __attribute__ ((packed)) |
| |
| static void | dump_frame (const u_char *frame, int frame_sz) |
| | Dump a datalink layer frame. More...
|
| |
| static void | prepare_sockaddr_ll (struct sockaddr_ll *soc_addr_ll, int ifindex, const u_char *ether_dst_addr) |
| | Prepare message header to be sent with sendmsg(). More...
|
| |
| static void | prepare_message (u_char *msg, struct sockaddr_ll *soc_addr_ll, u_char *payload, int payload_sz) |
| | Prepare message header to be sent with sendmsg(). More...
|
| |
| static int | send_frame (const u_char *frame, int frame_sz, int use_pcap, int timeout, char *filter, struct in6_addr *ipaddr, u_char **answer) |
| | Send a frame and listen to the answer. More...
|
| |
| static int | forge_frame (const u_char *ether_src_addr, const u_char *ether_dst_addr, int ether_proto, u_char *payload, int payload_sz, struct pseudo_frame **frame) |
| | Forge a datalink layer frame. More...
|
| |
| tree_cell * | nasl_forge_frame (lex_ctxt *lexic) |
| | Forge a datalink layer frame. More...
|
| |
| tree_cell * | nasl_send_frame (lex_ctxt *lexic) |
| | Send a frame and listen to the answer. More...
|
| |
| tree_cell * | nasl_dump_frame (lex_ctxt *lexic) |
| | Dump a datalink layer frame. More...
|
| |
| static int | get_local_mac_address_from_ip (char *ip_address, u_char *mac) |
| | Get the MAC address of host. More...
|
| |
| tree_cell * | nasl_get_local_mac_address_from_ip (lex_ctxt *lexic) |
| | Get the MAC address of host. More...
|
| |
| tree_cell * | nasl_send_arp_request (lex_ctxt *lexic) |
| | Send an arp request to an IP host. More...
|
| |
Functions to forge and manipulate datalink layer frames.
Definition in file nasl_frame_forgery.c.
◆ G_LOG_DOMAIN
| #define G_LOG_DOMAIN "lib misc" |
◆ __attribute__()
◆ dump_frame()
| static void dump_frame |
( |
const u_char * |
frame, |
|
|
int |
frame_sz |
|
) |
| |
|
static |
Dump a datalink layer frame.
- Parameters
-
| frame | The frame to be dumped. |
| frame_sz | The frame's size. |
Definition at line 63 of file nasl_frame_forgery.c.
67 printf (
"\nThe Frame:\n");
70 printf (
"%02x%02x ", ((u_char *) frame)[f], ((u_char *) frame)[f + 1]);
Referenced by nasl_dump_frame().
◆ forge_frame()
| static int forge_frame |
( |
const u_char * |
ether_src_addr, |
|
|
const u_char * |
ether_dst_addr, |
|
|
int |
ether_proto, |
|
|
u_char * |
payload, |
|
|
int |
payload_sz, |
|
|
struct pseudo_frame ** |
frame |
|
) |
| |
|
static |
Forge a datalink layer frame.
- Parameters
-
| [in] | src_haddr | Source MAC address to use. |
| [in] | dst_haddr | Destination MAC address to use. |
| [in] | ether_proto | Ethernet type integer in hex format. Default 0x0800 (ETHER_P_IP) |
| [in] | payload | Payload to be attached to the frame. E.g a forged tcp datagram, or arp header |
| [out] | frame | the forge frame |
- Returns
- the forged frame size.
Definition at line 230 of file nasl_frame_forgery.c.
239 memcpy ((*frame)->framehdr.h_dest, ether_dst_addr, ETHER_ADDR_LEN);
240 memcpy ((*frame)->framehdr.h_source, ether_src_addr, ETHER_ADDR_LEN);
241 (*frame)->framehdr.h_proto = htons (ether_proto);
244 frame_sz = ETH_HLEN + payload_sz;
245 memcpy ((
char *) *frame + ETH_HLEN,
payload, payload_sz);
References payload.
Referenced by nasl_forge_frame(), and nasl_send_arp_request().
◆ get_local_mac_address_from_ip()
| static int get_local_mac_address_from_ip |
( |
char * |
ip_address, |
|
|
u_char * |
mac |
|
) |
| |
|
static |
Get the MAC address of host.
- Parameters
-
| [in] | ip_address | Local IP address |
| [out] | mac | The MAC address |
- Returns
- 0 on success. MAC address is put into buffer. -1 on error.
Definition at line 389 of file nasl_frame_forgery.c.
393 char *if_name = NULL;
398 g_debug (
"%s: Missing interface name", __func__);
402 strncpy (ifr.ifr_name, if_name, sizeof (ifr.ifr_name) - 1);
404 ifr.ifr_name[
sizeof (ifr.ifr_name) - 1] =
'\0';
406 sock = socket (PF_INET, SOCK_STREAM, 0);
409 perror (
"socket() ");
413 if (-1 == ioctl (sock, SIOCGIFHWADDR, &ifr))
415 g_debug (
"%s: ioctl(SIOCGIFHWADDR)", __func__);
419 memcpy (
mac, (u_char *) ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
References get_iface_from_ip(), and mac().
Referenced by nasl_get_local_mac_address_from_ip(), and nasl_send_arp_request().
◆ nasl_dump_frame()
◆ nasl_forge_frame()
Forge a datalink layer frame.
@naslparams
src_haddr Source MAC address to use.
dst_haddr Destination MAC address to use.
ether_proto Ethernet type integer in hex format. Default 0x0800 (ETHER_P_IP)
payload Payload to be attached to the frame. E.g a forged tcp datagram.
- @naslreturn the forged frame.
- Parameters
-
| lexic | Lexical context of NASL interpreter. |
- Returns
- tree_cell element or null.
Definition at line 268 of file nasl_frame_forgery.c.
279 if (ether_src_addr == NULL || ether_dst_addr == NULL ||
payload == NULL)
282 "%s usage: payload, src_haddr and dst_haddr are mandatory "
288 frame_sz =
forge_frame ((u_char *) ether_src_addr, (u_char *) ether_dst_addr,
289 ether_proto,
payload, payload_sz, &frame);
293 retc->
size = frame_sz;
References alloc_typed_cell(), CONST_DATA, forge_frame(), get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), nasl_perror(), payload, TC::size, TC::str_val, and TC::x.
◆ nasl_get_local_mac_address_from_ip()
Get the MAC address of host.
@naslparam
- Parameters
-
| [in] | lexic | Lexical context of NASL interpreter. |
Definition at line 438 of file nasl_frame_forgery.c.
446 mac = g_malloc0 (
sizeof (u_char) * ETHER_ADDR_LEN);
450 buffer = g_strdup_printf (
"%02x:%02x:%02x:%02x:%02x:%02x",
mac[0],
mac[1],
References alloc_typed_cell(), CONST_DATA, get_local_mac_address_from_ip(), get_str_var_by_num(), mac(), TC::size, TC::str_val, and TC::x.
◆ nasl_send_arp_request()
Send an arp request to an IP host.
- NASL Returns:\n The MAC address of the target. NULL otherwise
- Parameters
-
| [in] | lexic | Lexical context of NASL interpreter. |
- Returns
- A tree cell or NULL.
Definition at line 471 of file nasl_frame_forgery.c.
475 struct in_addr dst_inaddr, src_inaddr;
479 char ip_src_str[INET6_ADDRSTRLEN];
480 u_char mac_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
481 u_char
mac[6], *mac_aux;
483 u_char *answer = NULL;
489 if (dst == NULL || (IN6_IS_ADDR_V4MAPPED (dst) != 1))
492 memset (&dst_inaddr,
'\0',
sizeof (
struct in_addr));
493 dst_inaddr.s_addr = dst->s6_addr32[3];
495 ipv4_as_ipv6 (&src_inaddr, &src);
498 addr6_to_str (&src, ip_src_str);
500 mac_aux = (u_char *) g_malloc0 (
sizeof (u_char) * 6);
512 eth_arp.arp_header.ar_hrd = htons (ARPHRD_ETHER);
513 eth_arp.arp_header.ar_pro = htons (ETHERTYPE_IP);
514 eth_arp.arp_header.ar_hln = ETH_ALEN;
515 eth_arp.arp_header.ar_pln = 4;
516 eth_arp.arp_header.ar_op = htons (ARPOP_REQUEST);
518 memcpy (&(eth_arp.__ar_sha),
mac, ETH_ALEN);
519 memcpy (&(eth_arp.__ar_sip), &src_inaddr, 4);
520 memcpy (&(eth_arp.__ar_tha), mac_broadcast_addr, ETH_ALEN);
521 memcpy (&(eth_arp.__ar_tip), &dst_inaddr, 4);
524 forge_frame (
mac, mac_broadcast_addr, ETH_P_ARP, (u_char *) ð_arp,
528 snprintf (filter,
sizeof (filter),
"arp and src host %s",
529 inet_ntoa (dst_inaddr));
532 send_frame ((
const u_char *) frame, frame_sz, 1, to, filter, dst, &answer);
536 g_message (
"%s: Not possible to send the frame", __func__);
540 if (answer && answer_sz > -1)
543 struct ether_header *answer_aux;
545 answer_aux = (
struct ether_header *) answer;
546 daddr = g_strdup_printf (
547 "%02x:%02x:%02x:%02x:%02x:%02x", (u_int) answer_aux->ether_shost[0],
548 (u_int) answer_aux->ether_shost[1], (u_int) answer_aux->ether_shost[2],
549 (u_int) answer_aux->ether_shost[3], (u_int) answer_aux->ether_shost[4],
550 (u_int) answer_aux->ether_shost[5]);
557 g_debug (
"%s: No answer received.", __func__);
References pseudo_eth_arp::__ar_sha, pseudo_eth_arp::__ar_sip, pseudo_eth_arp::__ar_tha, pseudo_eth_arp::__ar_tip, alloc_typed_cell(), pseudo_eth_arp::arp_header, CONST_DATA, daddr, forge_frame(), get_int_var_by_name(), get_local_mac_address_from_ip(), mac(), plug_get_host_ip(), routethrough(), struct_lex_ctxt::script_infos, send_frame(), TC::size, TC::str_val, and TC::x.
◆ nasl_send_frame()
Send a frame and listen to the answer.
@naslparams
frame The frame to be sent.
pcap_active TRUE by default. Otherwise, NASL does not listen for the answers.
pcap_filter BPF filter.
pcap_timeout Capture timeout. 5 by default.
- @naslreturn Sniffed answer.
- Parameters
-
| lexic | Lexical context of NASL interpreter. |
- Returns
- tree_cell element or null.
Definition at line 314 of file nasl_frame_forgery.c.
324 u_char *answer = NULL;
327 if (frame == NULL || frame_sz <= 0)
329 nasl_perror (lexic,
"%s usage: frame is a mandatory parameters.\n",
335 send_frame (frame, frame_sz, use_pcap, to, filter, ipaddr, &answer);
338 g_message (
"%s: Not possible to send the frame", __func__);
342 if (answer && answer_sz > -1)
346 retc->
size = answer_sz;
References alloc_typed_cell(), CONST_DATA, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), nasl_perror(), plug_get_host_ip(), struct_lex_ctxt::script_infos, send_frame(), TC::size, TC::str_val, and TC::x.
◆ prepare_message()
| static void prepare_message |
( |
u_char * |
msg, |
|
|
struct sockaddr_ll * |
soc_addr_ll, |
|
|
u_char * |
payload, |
|
|
int |
payload_sz |
|
) |
| |
|
static |
Prepare message header to be sent with sendmsg().
- Parameters
-
| [out] | msg | The packaged messages to be sent |
| [in] | soc_addr_ll | The sockaddr_ll structure for capturing |
| [in] | payload | The payload, a datalink layer frame with payload |
| [in] | payload_sz | The payload size. |
Definition at line 103 of file nasl_frame_forgery.c.
107 struct msghdr *message;
110 iov.iov_len = payload_sz;
112 message = g_malloc0 (
sizeof (
struct msghdr) + payload_sz);
114 message->msg_name = soc_addr_ll;
115 message->msg_namelen =
sizeof (
struct sockaddr_ll);
116 message->msg_iov = &iov;
117 message->msg_iovlen = 1;
118 message->msg_control = 0;
119 message->msg_controllen = 0;
121 memcpy (msg, (u_char *) message,
sizeof (
struct msghdr) + payload_sz);
References payload.
Referenced by send_frame().
◆ prepare_sockaddr_ll()
| static void prepare_sockaddr_ll |
( |
struct sockaddr_ll * |
soc_addr_ll, |
|
|
int |
ifindex, |
|
|
const u_char * |
ether_dst_addr |
|
) |
| |
|
static |
Prepare message header to be sent with sendmsg().
- Parameters
-
| [out] | soc_addr_ll | The sockaddr_ll structure to be prepared |
| [in] | ifindex | The interface index to be use for capturing. |
| [in] | ether_dst_addr | The dst MAC address. |
Definition at line 85 of file nasl_frame_forgery.c.
88 soc_addr_ll->sll_family = AF_PACKET;
89 soc_addr_ll->sll_ifindex = ifindex;
90 soc_addr_ll->sll_halen = ETHER_ADDR_LEN;
91 soc_addr_ll->sll_protocol = htons (ETH_P_ALL);
92 memcpy (soc_addr_ll->sll_addr, ether_dst_addr, ETHER_ADDR_LEN);
Referenced by send_frame().
◆ send_frame()
| static int send_frame |
( |
const u_char * |
frame, |
|
|
int |
frame_sz, |
|
|
int |
use_pcap, |
|
|
int |
timeout, |
|
|
char * |
filter, |
|
|
struct in6_addr * |
ipaddr, |
|
|
u_char ** |
answer |
|
) |
| |
|
static |
Send a frame and listen to the answer.
- Parameters
-
Definition at line 141 of file nasl_frame_forgery.c.
148 int frame_and_payload = 0;
152 soc = socket (AF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
155 g_debug (
"%s: %s", __func__, strerror (errno));
162 g_message (
"%s: Missing interface index\n", __func__);
167 u_char dst_haddr[ETHER_ADDR_LEN];
168 memcpy (&dst_haddr, (
struct pseudo_frame *) frame, ETHER_ADDR_LEN);
170 struct sockaddr_ll soc_addr;
171 memset (&soc_addr,
'\0',
sizeof (
struct sockaddr_ll));
175 if (use_pcap != 0 && bpf < 0)
177 if (IN6_IS_ADDR_V4MAPPED (ipaddr))
179 struct in_addr sin, this_host;
180 memset (&sin,
'\0',
sizeof (
struct in_addr));
181 memset (&this_host,
'\0',
sizeof (
struct in_addr));
182 sin.s_addr = ipaddr->s6_addr32[3];
187 struct in6_addr this_host;
188 memset (&this_host,
'\0',
sizeof (
struct in6_addr));
194 message = g_malloc0 (
sizeof (
struct msghdr) + frame_sz);
197 int b = sendmsg (soc, (
struct msghdr *) message, 0);
201 g_message (
"%s: Error sending message: %s", __func__, strerror (errno));
References bpf_close(), capture_next_frame(), get_iface_index(), init_capture_device(), init_v6_capture_device(), prepare_message(), and prepare_sockaddr_ll().
Referenced by nasl_send_arp_request(), and nasl_send_frame().
◆ __ar_sha
| u_char __ar_sha[ETH_ALEN] |
◆ __ar_sip
◆ __ar_tha
| u_char __ar_tha[ETH_ALEN] |
◆ __ar_tip
◆ __zero_padding
| u_char __zero_padding[18] |
◆ arp_header
◆ framehdr
◆ payload
static void prepare_sockaddr_ll(struct sockaddr_ll *soc_addr_ll, int ifindex, const u_char *ether_dst_addr)
Prepare message header to be sent with sendmsg().
char * capture_next_frame(int bpf, int timeout, int *sz, int dl_layer_only)
Capture a link layer frame.
int get_var_size_by_name(lex_ctxt *, const char *)
struct in6_addr * plug_get_host_ip(struct script_infos *args)
static int get_local_mac_address_from_ip(char *ip_address, u_char *mac)
Get the MAC address of host.
static int forge_frame(const u_char *ether_src_addr, const u_char *ether_dst_addr, int ether_proto, u_char *payload, int payload_sz, struct pseudo_frame **frame)
Forge a datalink layer frame.
char * get_str_var_by_name(lex_ctxt *, const char *)
static void dump_frame(const u_char *frame, int frame_sz)
Dump a datalink layer frame.
char * get_iface_from_ip(const char *local_ip)
Given an IP address, determines which interface belongs to.
int init_capture_device(struct in_addr src, struct in_addr dest, char *filter)
Set up the pcap filter, and select the correct interface.
static void prepare_message(u_char *msg, struct sockaddr_ll *soc_addr_ll, u_char *payload, int payload_sz)
Prepare message header to be sent with sendmsg().
void nasl_perror(lex_ctxt *lexic, char *msg,...)
int get_iface_index(struct in6_addr *ipaddr, int *ifindex)
Get the interface index depending on the target's IP.
long int get_int_var_by_name(lex_ctxt *, const char *, int)
char * get_str_var_by_num(lex_ctxt *, int)
struct script_infos * script_infos
gpg_err_code_t mac(const char *key, const size_t key_len, const char *data, const size_t data_len, const char *iv, const size_t iv_len, int algo, int flags, char **out, size_t *out_len)
static int send_frame(const u_char *frame, int frame_sz, int use_pcap, int timeout, char *filter, struct in6_addr *ipaddr, u_char **answer)
Send a frame and listen to the answer.
tree_cell * alloc_typed_cell(int typ)
int init_v6_capture_device(struct in6_addr src, struct in6_addr dest, char *filter)
char * routethrough(struct in_addr *dest, struct in_addr *source)
An awesome function to determine what interface a packet to a given destination should be routed thro...