OpenVAS Scanner 23.40.3
nasl_packet_forgery_v6.c File Reference

NASL IPv6 Packet Forgery functions. More...

#include <arpa/inet.h>
#include <ctype.h>
#include <pcap.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/time.h>
#include <unistd.h>
#include "../misc/bpf_share.h"
#include "../misc/pcap_openvas.h"
#include "../misc/plugutils.h"
#include "capture_packet.h"
#include "exec.h"
#include "nasl_debug.h"
#include "nasl_func.h"
#include "nasl_global_ctxt.h"
#include "nasl_lex_ctxt.h"
#include "nasl_packet_forgery_v6.h"
#include "nasl_raw.h"
#include "nasl_socket.h"
#include "nasl_tree.h"
#include "nasl_var.h"
#include <netinet/icmp6.h>
Include dependency graph for nasl_packet_forgery_v6.c:

Go to the source code of this file.

Data Structures

struct  v6pseudohdr
struct  tcp_opt_mss
struct  tcp_opt_wscale
struct  tcp_opt_sack_perm
struct  tcp_opt_tstamp
struct  tcp_options
struct  v6pseudo_udp_hdr
struct  v6pseudo_icmp_hdr
struct  igmp6_hdr

Macros

#define FIX(n)
#define UNFIX(n)
#define rnd_tcp_port()

Functions

static int np_in_cksum (u_short *p, int n)
tree_cellforge_ip_v6_packet (lex_ctxt *lexic)
 Forge an IPv6 packet.
tree_cellget_ip_v6_element (lex_ctxt *lexic)
 Obtain IPv6 header element.
tree_cellset_ip_v6_elements (lex_ctxt *lexic)
 Set IPv6 header element.
tree_celldump_ip_v6_packet (lex_ctxt *lexic)
 Print IPv6 Header.
tree_cellinsert_ip_v6_options (lex_ctxt *lexic)
 Adds an IPv6 option to the datagram.
struct v6pseudohdr __attribute__ ((packed))
tree_cellforge_tcp_v6_packet (lex_ctxt *lexic)
 Forge TCP packet.
tree_cellget_tcp_v6_element (lex_ctxt *lexic)
 Get TCP Header element.
static void get_tcp_options (char *options, struct tcp_options *tcp_all_options)
 Extract all TCP option from an IP datagram.
tree_cellget_tcp_v6_option (lex_ctxt *lexic)
 Get a TCP option from an IP datagram if present. Possible options are: TCPOPT_MAXSEG (2), values between 536 and 65535 TCPOPT_WINDOW (3), with values between 0 and 14 TCPOPT_SACK_PERMITTED (4), no value required. TCPOPT_TIMESTAMP (8), 8 bytes value for timestamp and echo timestamp, 4 bytes each one.
tree_cellset_tcp_v6_elements (lex_ctxt *lexic)
 Set TCP Header element.
tree_cellinsert_tcp_v6_options (lex_ctxt *lexic)
 Add options to a TCP segment header. Possible options are: TCPOPT_MAXSEG (2), values between 536 and 65535 TCPOPT_WINDOW (3), with values between 0 and 14 TCPOPT_SACK_PERMITTED (4), no value required. TCPOPT_TIMESTAMP (8), 8 bytes value for timestamp and echo timestamp, 4 bytes each one.
tree_celldump_tcp_v6_packet (lex_ctxt *lexic)
 Dump TCP part of an IPv6 Datagram.
tree_cellforge_udp_v6_packet (lex_ctxt *lexic)
tree_cellget_udp_v6_element (lex_ctxt *lexic)
tree_cellset_udp_v6_elements (lex_ctxt *lexic)
tree_celldump_udp_v6_packet (lex_ctxt *lexic)
tree_cellforge_icmp_v6_packet (lex_ctxt *lexic)
tree_cellget_icmp_v6_element (lex_ctxt *lexic)
tree_celldump_icmp_v6_packet (lex_ctxt *lexic)
 Dump the ICMP part of a IP Datagram.
tree_cellforge_igmp_v6_packet (lex_ctxt *lexic)
tree_cellnasl_tcp_v6_ping (lex_ctxt *lexic)
 Performs TCP Connect to test if host is alive.
tree_cellnasl_send_v6packet (lex_ctxt *lexic)
 Send forged IPv6 Packets.

Variables

struct in6_addr s6addr
struct in6_addr d6addr
u_short length
u_char zero1
u_char zero2
u_char zero3
u_char protocol
struct tcphdr tcpheader
uint8_t kind
uint8_t len
uint16_t mss
uint8_t wscale
uint32_t tstamp
uint32_t e_tstamp
struct tcp_opt_sack_perm sack_perm
struct v6pseudo_udp_hdr __attribute__

Detailed Description

NASL IPv6 Packet Forgery functions.

Provides IPv6 Packet Forgery functionalities The API set offers forgery for,

  1. TCP
  2. IPv6

Definition in file nasl_packet_forgery_v6.c.

Macro Definition Documentation

◆ FIX

#define FIX ( n)
Value:
htons (n)
Todo
: It still needs to be taken care BSD_BYTE_ORDERING gets here if defined (e.g. by config.h)

Definition at line 63 of file nasl_packet_forgery_v6.c.

Referenced by __attribute__(), forge_icmp_v6_packet(), forge_igmp_v6_packet(), forge_ip_v6_packet(), forge_tcp_v6_packet(), forge_udp_v6_packet(), insert_tcp_v6_options(), nasl_tcp_v6_ping(), set_tcp_v6_elements(), and set_udp_v6_elements().

◆ rnd_tcp_port

#define rnd_tcp_port ( )
Value:
(rand () % 65535 + 1024)

Referenced by nasl_tcp_v6_ping().

◆ UNFIX

Function Documentation

◆ __attribute__()

struct v6pseudohdr __attribute__ ( (packed) )

◆ dump_icmp_v6_packet()

tree_cell * dump_icmp_v6_packet ( lex_ctxt * lexic)

Dump the ICMP part of a IP Datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]...IP datagrams to dump the ICMP part from.

Definition at line 2054 of file nasl_packet_forgery_v6.c.

2055{
2056 int i = 0;
2057 u_char *pkt;
2058 while ((pkt = (u_char *) get_str_var_by_num (lexic, i++)) != NULL)
2059 {
2060 unsigned int j;
2061 unsigned int limit;
2062 char *c;
2063 struct ip6_hdr *ip6 = (struct ip6_hdr *) pkt;
2064 struct icmp6_hdr *icmp;
2065 icmp = (struct icmp6_hdr *) (pkt + 40);
2066 limit = get_var_size_by_num (lexic, i - 1);
2067 printf ("------\n");
2068 printf ("\ticmp6_id : %d\n", ntohs (icmp->icmp6_id));
2069 printf ("\ticmp6_code : %d\n", icmp->icmp6_code);
2070 printf ("\ticmp6_type : %u\n", icmp->icmp6_type);
2071 printf ("\ticmp6_seq : %u\n", ntohs (icmp->icmp6_seq));
2072 printf ("\ticmp6_cksum : %d\n", ntohs (icmp->icmp6_cksum));
2073 printf ("\tData : ");
2074 c = (char *) ((char *) icmp + sizeof (struct icmp6_hdr));
2075 if (UNFIX (ip6->ip6_plen) > (sizeof (struct icmp6_hdr)))
2076 for (j = 0;
2077 j < UNFIX (ip6->ip6_plen) - sizeof (struct icmp6_hdr) && j < limit;
2078 j++)
2079 printf ("%c", isprint (c[j]) ? c[j] : '.');
2080 printf ("\n");
2081 }
2082 return NULL;
2083}
long int get_var_size_by_num(lex_ctxt *, int)
Definition nasl_var.c:1145
char * get_str_var_by_num(lex_ctxt *, int)
Definition nasl_var.c:1108
#define UNFIX(n)
#define UNFIX(n)

References get_str_var_by_num(), get_var_size_by_num(), and UNFIX.

Here is the call graph for this function:

◆ dump_ip_v6_packet()

tree_cell * dump_ip_v6_packet ( lex_ctxt * lexic)

Print IPv6 Header.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]...IPv6 datagrams to dump.
Returns
Print and returns FAKE_CELL.

Definition at line 337 of file nasl_packet_forgery_v6.c.

338{
339 int i;
340 char addr[INET6_ADDRSTRLEN];
341
342 for (i = 0;; i++)
343 {
344 struct ip6_hdr *ip6 = (struct ip6_hdr *) get_str_var_by_num (lexic, i);
345
346 if (ip6 == NULL)
347 break;
348 else
349 {
350 printf ("------\n");
351 printf ("\tip6_v : %d\n", ntohl (ip6->ip6_flow) >> 28);
352 printf ("\tip6_tc : %d\n", (ntohl (ip6->ip6_flow) >> 20) & 0xff);
353 printf ("\tip6_fl : %d\n", ntohl (ip6->ip6_flow) & 0x3ffff);
354 printf ("\tip6_plen : %d\n", UNFIX (ip6->ip6_plen));
355 printf ("\tip6_hlim : %d\n", ip6->ip6_hlim);
356 switch (ip6->ip6_nxt)
357 {
358 case IPPROTO_TCP:
359 printf ("\tip6_nxt : IPPROTO_TCP (%d)\n", ip6->ip6_nxt);
360 break;
361 case IPPROTO_UDP:
362 printf ("\tip6_nxt : IPPROTO_UDP (%d)\n", ip6->ip6_nxt);
363 break;
364 case IPPROTO_ICMPV6:
365 printf ("\tip6_nxt : IPPROTO_ICMPV6 (%d)\n", ip6->ip6_nxt);
366 break;
367 default:
368 printf ("\tip6_nxt : %d\n", ip6->ip6_nxt);
369 break;
370 }
371 printf ("\tip6_src : %s\n",
372 inet_ntop (AF_INET6, &ip6->ip6_src, addr, sizeof (addr)));
373 printf ("\tip6_dst : %s\n",
374 inet_ntop (AF_INET6, &ip6->ip6_dst, addr, sizeof (addr)));
375 printf ("\n");
376 }
377 }
378
379 return FAKE_CELL;
380}
#define FAKE_CELL
Definition nasl_tree.h:110

References FAKE_CELL, get_str_var_by_num(), and UNFIX.

Here is the call graph for this function:

◆ dump_tcp_v6_packet()

tree_cell * dump_tcp_v6_packet ( lex_ctxt * lexic)

Dump TCP part of an IPv6 Datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]...IPv6 datagrams to dump.
Returns
Print and return FAKE_CELL.

Definition at line 1250 of file nasl_packet_forgery_v6.c.

1251{
1252 int i = 0;
1253 u_char *pkt;
1254 int options_len = 0;
1255
1256 while ((pkt = (u_char *) get_str_var_by_num (lexic, i++)) != NULL)
1257 {
1258 int a = 0;
1259 struct ip6_hdr *ip6 = (struct ip6_hdr *) pkt;
1260 struct tcphdr *tcp = (struct tcphdr *) (pkt + 40);
1261 unsigned int j;
1262 unsigned int limit;
1263 char *c;
1264
1265 limit = get_var_size_by_num (lexic, i - 1);
1266
1267 printf ("------\n");
1268 printf ("\tth_sport : %d\n", ntohs (tcp->th_sport));
1269 printf ("\tth_dport : %d\n", ntohs (tcp->th_dport));
1270 printf ("\tth_seq : %u\n", (unsigned int) ntohl (tcp->th_seq));
1271 printf ("\tth_ack : %u\n", (unsigned int) ntohl (tcp->th_ack));
1272 printf ("\tth_x2 : %d\n", tcp->th_x2);
1273 printf ("\tth_off : %d\n", tcp->th_off);
1274 printf ("\tth_flags : ");
1275 if (tcp->th_flags & TH_FIN)
1276 {
1277 printf ("TH_FIN");
1278 a++;
1279 }
1280 if (tcp->th_flags & TH_SYN)
1281 {
1282 if (a)
1283 printf ("|");
1284 printf ("TH_SYN");
1285 a++;
1286 }
1287 if (tcp->th_flags & TH_RST)
1288 {
1289 if (a)
1290 printf ("|");
1291 printf ("TH_RST");
1292 a++;
1293 }
1294 if (tcp->th_flags & TH_PUSH)
1295 {
1296 if (a)
1297 printf ("|");
1298 printf ("TH_PUSH");
1299 a++;
1300 }
1301 if (tcp->th_flags & TH_ACK)
1302 {
1303 if (a)
1304 printf ("|");
1305 printf ("TH_ACK");
1306 a++;
1307 }
1308 if (tcp->th_flags & TH_URG)
1309 {
1310 if (a)
1311 printf ("|");
1312 printf ("TH_URG");
1313 a++;
1314 }
1315 if (!a)
1316 printf ("0");
1317 else
1318 printf (" (%d)", tcp->th_flags);
1319 printf ("\n");
1320 printf ("\tth_win : %d\n", ntohs (tcp->th_win));
1321 printf ("\tth_sum : 0x%x\n", tcp->th_sum);
1322 printf ("\tth_urp : %d\n", tcp->th_urp);
1323
1324 options_len = sizeof (uint8_t) * 4 * (tcp->th_off - 5);
1325
1326 if (options_len > 5) // Options present
1327 {
1328 char *options;
1329 struct tcp_options *tcp_all_options;
1330
1331 options = (char *) g_malloc0 (options_len);
1332 memcpy (options, (char *) tcp + 20, options_len);
1333
1334 tcp_all_options = g_malloc0 (sizeof (struct tcp_options));
1335 get_tcp_options (options, tcp_all_options);
1336 if (tcp_all_options != NULL)
1337 {
1338 printf ("\tTCP Options:\n");
1339 printf ("\t\tTCPOPT_MAXSEG: %u\n",
1340 ntohs ((uint16_t) tcp_all_options->mss.mss));
1341 printf ("\t\tTCPOPT_WINDOW: %u\n",
1342 tcp_all_options->wscale.wscale);
1343 printf ("\t\tTCPOPT_SACK_PERMITTED: %u\n",
1344 tcp_all_options->sack_perm.kind ? 1 : 0);
1345 printf ("\t\tTCPOPT_TIMESTAMP TSval: %u\n",
1346 ntohl ((uint32_t) tcp_all_options->tstamp.tstamp));
1347 printf ("\t\tTCPOPT_TIMESTAMP TSecr: %u\n",
1348 ntohl ((uint32_t) tcp_all_options->tstamp.e_tstamp));
1349 }
1350 g_free (options);
1351 g_free (tcp_all_options);
1352 }
1353 printf ("\n\tData : ");
1354 c = (char *) ((char *) tcp + sizeof (struct tcphdr) + options_len);
1355 if (UNFIX (ip6->ip6_plen) > (sizeof (struct tcphdr) + options_len))
1356 for (j = 0;
1357 j < UNFIX (ip6->ip6_plen) - sizeof (struct tcphdr) - options_len
1358 && j < limit;
1359 j++)
1360 printf ("%c", isprint (c[j]) ? c[j] : '.');
1361 printf ("\n");
1362 printf ("\n");
1363 }
1364 return NULL;
1365}
static void get_tcp_options(char *options, struct tcp_options *tcp_all_options)
Extract all TCP option from an IP datagram.
struct tcp_opt_wscale wscale
struct tcp_opt_mss mss
struct tcp_opt_tstamp tstamp
struct tcp_opt_sack_perm sack_perm

References tcp_opt_tstamp::e_tstamp, get_str_var_by_num(), get_tcp_options(), get_var_size_by_num(), tcp_opt_sack_perm::kind, tcp_opt_mss::mss, tcp_options::mss, tcp_options::sack_perm, tcp_opt_tstamp::tstamp, tcp_options::tstamp, UNFIX, tcp_opt_wscale::wscale, and tcp_options::wscale.

Here is the call graph for this function:

◆ dump_udp_v6_packet()

tree_cell * dump_udp_v6_packet ( lex_ctxt * lexic)

Definition at line 1662 of file nasl_packet_forgery_v6.c.

1663{
1664 int i = 0;
1665 u_char *pkt;
1666 while ((pkt = (u_char *) get_str_var_by_num (lexic, i++)) != NULL)
1667 {
1668 struct udphdr *udp = (struct udphdr *) (pkt + sizeof (struct ip6_hdr));
1669 unsigned int j;
1670 char *c;
1671 unsigned int limit = get_var_size_by_num (lexic, i - 1);
1672 printf ("------\n");
1673 printf ("\tuh_sport : %d\n", ntohs (udp->uh_sport));
1674 printf ("\tuh_dport : %d\n", ntohs (udp->uh_dport));
1675 printf ("\tuh_sum : 0x%x\n", udp->uh_sum);
1676 printf ("\tuh_ulen : %d\n", ntohs (udp->uh_ulen));
1677 printf ("\tdata : ");
1678 c = (char *) udp;
1679 if (udp->uh_ulen > sizeof (struct udphdr))
1680 for (j = sizeof (struct udphdr); j < ntohs (udp->uh_ulen) && j < limit;
1681 j++)
1682 printf ("%c", isprint (c[j]) ? c[j] : '.');
1683
1684 printf ("\n");
1685 }
1686 return NULL;
1687}

References get_str_var_by_num(), and get_var_size_by_num().

Here is the call graph for this function:

◆ forge_icmp_v6_packet()

tree_cell * forge_icmp_v6_packet ( lex_ctxt * lexic)

Definition at line 1726 of file nasl_packet_forgery_v6.c.

1727{
1728 tree_cell *retc = NULL;
1729 struct ip6_hdr *ip6;
1730 struct ip6_hdr *ip6_icmp;
1731 size_t ip6_sz, size = 0, sz = 0;
1732 struct icmp6_hdr *icmp;
1733 struct nd_router_solicit *routersolicit = NULL;
1734 struct nd_router_advert *routeradvert = NULL;
1735 struct nd_neighbor_solicit *neighborsolicit = NULL;
1736 struct nd_neighbor_advert *neighboradvert = NULL;
1737
1738 char *data, *p;
1739 size_t len;
1740 u_char *pkt;
1741 int t;
1742 ip6 = (struct ip6_hdr *) get_str_var_by_name (lexic, "ip6");
1743 ip6_sz = get_var_size_by_name (lexic, "ip6");
1744
1745 if (ip6 != NULL)
1746 {
1748 data = get_str_var_by_name (lexic, "data");
1749 len = data == NULL ? 0 : get_var_size_by_name (lexic, "data");
1750 t = get_int_var_by_name (lexic, "icmp_type", 0);
1751 if (40 > ip6_sz)
1752 return NULL;
1753
1754 /* ICMP header size is 8 */
1755 pkt = g_malloc0 (ip6_sz + 8 + len);
1756 ip6_icmp = (struct ip6_hdr *) pkt;
1757
1758 bcopy (ip6, ip6_icmp, ip6_sz);
1759 p = (char *) (pkt + ip6_sz);
1760 icmp = (struct icmp6_hdr *) p;
1761
1762 icmp->icmp6_code = get_int_var_by_name (lexic, "icmp_code", 0);
1763 icmp->icmp6_type = t;
1764
1765 switch (t)
1766 {
1767 case ICMP6_ECHO_REQUEST:
1768 {
1769 if (data != NULL)
1770 bcopy (data, &(p[8]), len);
1771 icmp->icmp6_id = get_int_var_by_name (lexic, "icmp_id", 0);
1772 icmp->icmp6_seq = get_int_var_by_name (lexic, "icmp_seq", 0);
1773 size = ip6_sz + 8 + len;
1774 sz = 8;
1775 }
1776 break;
1777 case ND_ROUTER_SOLICIT:
1778 {
1779 pkt =
1780 g_realloc (pkt, ip6_sz + sizeof (struct nd_router_solicit) + len);
1781 p = (char *) (pkt + ip6_sz);
1782 // Update ip6_icmp because it gets used again below
1783 ip6_icmp = (struct ip6_hdr *) pkt;
1784 routersolicit = (struct nd_router_solicit *) p;
1785 ((struct icmp6_hdr *) routersolicit)->icmp6_type = icmp->icmp6_type;
1786 ((struct icmp6_hdr *) routersolicit)->icmp6_code = icmp->icmp6_code;
1787 ((struct icmp6_hdr *) routersolicit)->icmp6_cksum =
1788 icmp->icmp6_cksum;
1789 size = ip6_sz + sizeof (struct nd_router_solicit) + len;
1790 sz = 4; /*type-1 byte, code-1byte, cksum-2bytes */
1791 }
1792 break;
1793 case ND_ROUTER_ADVERT:
1794 {
1795 pkt =
1796 g_realloc (pkt, ip6_sz + sizeof (struct nd_router_advert) + len);
1797 p = (char *) (pkt + ip6_sz);
1798 // Update ip6_icmp because it gets used again below
1799 ip6_icmp = (struct ip6_hdr *) pkt;
1800 // Let routeradvert point to routeradvert location in pkt
1801 routeradvert = (struct nd_router_advert *) p;
1802 // Set icmp6 header members
1803 ((struct icmp6_hdr *) routeradvert)->icmp6_type = icmp->icmp6_type;
1804 ((struct icmp6_hdr *) routeradvert)->icmp6_code = icmp->icmp6_code;
1805 ((struct icmp6_hdr *) routeradvert)->icmp6_cksum =
1806 icmp->icmp6_cksum;
1807 routeradvert->nd_ra_reachable =
1808 get_int_var_by_name (lexic, "reachable_time", 0);
1809 routeradvert->nd_ra_retransmit =
1810 get_int_var_by_name (lexic, "retransmit_timer", 0);
1811 routeradvert->nd_ra_curhoplimit = ip6_icmp->ip6_hlim;
1812 routeradvert->nd_ra_flags_reserved =
1813 get_int_var_by_name (lexic, "flags", 0);
1814 size = ip6_sz + sizeof (struct nd_router_advert) + len;
1815 sz = 5; /*type-1 byte, code-1byte, cksum-2bytes, current
1816 hoplimit-1byte */
1817 }
1818 break;
1819 case ND_NEIGHBOR_SOLICIT:
1820 {
1821 // Make room for nd_neighbor_solicit.nd_ns_target in packet
1822 pkt = g_realloc (pkt, ip6_sz + sizeof (struct nd_neighbor_solicit)
1823 + len);
1824 // Let p point to the start of nd_neighbor_solicit
1825 p = (char *) (pkt + ip6_sz);
1826 // Update ip6_icmp because it gets used again below
1827 ip6_icmp = (struct ip6_hdr *) pkt;
1828 // Fill in user date if provided
1829 if (data != NULL)
1830 memmove (&(p[8 + 16]), data, len);
1831 // Let neighborsolicit point to nd_neighbor_solicit location in pkt
1832 neighborsolicit = (struct nd_neighbor_solicit *) p;
1833 // Set icmp6 header members
1834 ((struct icmp6_hdr *) neighborsolicit)->icmp6_type =
1835 icmp->icmp6_type;
1836 ((struct icmp6_hdr *) neighborsolicit)->icmp6_code =
1837 icmp->icmp6_code;
1838 ((struct icmp6_hdr *) neighborsolicit)->icmp6_cksum =
1839 icmp->icmp6_cksum;
1840 // Set nd_ns_target
1841 memcpy (&neighborsolicit->nd_ns_target, &ip6_icmp->ip6_dst,
1842 sizeof (struct in6_addr)); /*dst ip should be link local */
1843 size = ip6_sz + sizeof (struct nd_neighbor_solicit) + len;
1844 sz = 4; /*type-1 byte, code-1byte, cksum-2bytes */
1845 }
1846 break;
1847 case ND_NEIGHBOR_ADVERT:
1848 {
1849 pkt = g_realloc (pkt,
1850 ip6_sz + sizeof (struct nd_neighbor_advert) + len);
1851 // Update ip6_icmp because it gets used again below
1852 ip6_icmp = (struct ip6_hdr *) pkt;
1853 p = (char *) (pkt + 40);
1854 neighboradvert = (struct nd_neighbor_advert *) p;
1855 // Set icmp6 header members
1856 ((struct icmp6_hdr *) neighboradvert)->icmp6_type =
1857 icmp->icmp6_type;
1858 ((struct icmp6_hdr *) neighboradvert)->icmp6_code =
1859 icmp->icmp6_code;
1860 ((struct icmp6_hdr *) neighboradvert)->icmp6_cksum =
1861 icmp->icmp6_cksum;
1862 neighboradvert->nd_na_flags_reserved =
1863 get_int_var_by_name (lexic, "flags", 0);
1864 if (neighboradvert->nd_na_flags_reserved & 0x00000020)
1865 memcpy (
1866 &neighboradvert->nd_na_target, &ip6_icmp->ip6_src,
1867 sizeof (struct in6_addr)); /*dst ip should be link local */
1868 else
1869 {
1870 if (get_var_size_by_name (lexic, "target") != 0)
1871 inet_pton (AF_INET6, get_str_var_by_name (lexic, "target"),
1872 &neighboradvert->nd_na_target);
1873 else
1874 {
1875 nasl_perror (lexic,
1876 "forge_icmp_v6_packet: missing 'target' "
1877 "parameter required for constructing response "
1878 "to a Neighbor Solicitation\n");
1879 g_free (ip6_icmp);
1880 return NULL;
1881 }
1882 }
1883 size = ip6_sz + sizeof (struct nd_neighbor_advert) + len;
1884 sz = 4; /*type-1 byte, code-1byte, cksum-2bytes */
1885 }
1886 break;
1887 default:
1888 {
1889 if (t < 0 || t > 255)
1890 {
1891 nasl_perror (lexic, "forge_icmp_v6_packet: illegal type %d\n",
1892 t);
1893 }
1894 else
1895 {
1896 if (data != NULL)
1897 bcopy (data, &(p[8]), len);
1898 icmp->icmp6_id = get_int_var_by_name (lexic, "icmp_id", 0);
1899 icmp->icmp6_seq = get_int_var_by_name (lexic, "icmp_seq", 0);
1900 size = ip6_sz + 8 + len;
1901 sz = 8;
1902 }
1903 }
1904 }
1905
1906 if (UNFIX (ip6_icmp->ip6_ctlun.ip6_un1.ip6_un1_plen) <= 40)
1907 {
1908 if (get_int_var_by_name (lexic, "update_ip_len", 1) != 0)
1909 {
1910 ip6_icmp->ip6_ctlun.ip6_un1.ip6_un1_plen = FIX (size - ip6_sz);
1911 }
1912 }
1913 if (get_int_var_by_name (lexic, "icmp_cksum", -1) == -1)
1914 {
1916 char *icmpsumdata =
1917 g_malloc0 (sizeof (struct v6pseudo_icmp_hdr) + len + 1);
1918
1919 bzero (&pseudohdr, sizeof (struct v6pseudo_icmp_hdr));
1920 memcpy (&pseudohdr.s6addr, &ip6->ip6_src, sizeof (struct in6_addr));
1921 memcpy (&pseudohdr.d6addr, &ip6->ip6_dst, sizeof (struct in6_addr));
1922
1923 pseudohdr.proto = 0x3a; /*ICMPv6 */
1924 pseudohdr.len = htons (size - ip6_sz);
1925 bcopy ((char *) icmp, (char *) &pseudohdr.icmpheader, sz);
1926 bcopy ((char *) &pseudohdr, icmpsumdata, sizeof (pseudohdr));
1927 if (data != NULL)
1928 bcopy ((char *) data, icmpsumdata + sizeof (pseudohdr), len);
1929 icmp->icmp6_cksum =
1930 np_in_cksum ((unsigned short *) icmpsumdata, size);
1931 g_free (icmpsumdata);
1932 }
1933 else
1934 icmp->icmp6_cksum =
1935 htons (get_int_var_by_name (lexic, "icmp_cksum", 0));
1936 switch (t)
1937 {
1938 case ICMP6_ECHO_REQUEST:
1939 break;
1940 case ND_ROUTER_SOLICIT:
1941 {
1942 routersolicit->nd_rs_hdr.icmp6_cksum = icmp->icmp6_cksum;
1943 }
1944 break;
1945 case ND_ROUTER_ADVERT:
1946 {
1947 routeradvert->nd_ra_hdr.icmp6_cksum = icmp->icmp6_cksum;
1948 }
1949 break;
1950 case ND_NEIGHBOR_SOLICIT:
1951 {
1952 neighborsolicit->nd_ns_hdr.icmp6_cksum = icmp->icmp6_cksum;
1953 }
1954 break;
1955 case ND_NEIGHBOR_ADVERT:
1956 {
1957 neighboradvert->nd_na_hdr.icmp6_cksum = icmp->icmp6_cksum;
1958 }
1959 break;
1960 default:
1961 {
1962 }
1963 }
1964
1965 retc->x.str_val = (char *) pkt;
1966 retc->size = size;
1967 }
1968 else
1969 nasl_perror (lexic, "forge_icmp_v6_packet: missing 'ip6' parameter\n");
1970
1971 return retc;
1972}
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition nasl_debug.c:105
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1118
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition nasl_var.c:1101
long int get_var_size_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1138
uint8_t len
#define FIX(n)
static int np_in_cksum(u_short *p, int n)
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ CONST_DATA
Definition nasl_tree.h:82
struct TC tree_cell
long int size
Definition nasl_tree.h:99
union TC::@332262321161220155002104006201360276211317150140 x
char * str_val
Definition nasl_tree.h:103

References alloc_typed_cell(), CONST_DATA, FIX, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), len, nasl_perror(), np_in_cksum(), TC::size, TC::str_val, UNFIX, and TC::x.

Here is the call graph for this function:

◆ forge_igmp_v6_packet()

tree_cell * forge_igmp_v6_packet ( lex_ctxt * lexic)

Definition at line 2111 of file nasl_packet_forgery_v6.c.

2112{
2113 struct ip6_hdr *ip6 = (struct ip6_hdr *) get_str_var_by_name (lexic, "ip6");
2114
2115 if (ip6 != NULL)
2116 {
2117 char *data = get_str_var_by_name (lexic, "data");
2118 size_t len = data ? get_var_size_by_name (lexic, "data") : 0;
2119 u_char *pkt = g_malloc0 (sizeof (struct igmp6_hdr) + 40 + len);
2120 struct ip6_hdr *ip6_igmp = (struct ip6_hdr *) pkt;
2121 struct igmp6_hdr *igmp;
2122 char *p;
2123 char *grp;
2124 tree_cell *retc;
2125 size_t ipsz = get_var_size_by_name (lexic, "ip6");
2126
2127 bcopy (ip6, ip6_igmp, ipsz);
2128
2129 if (UNFIX (ip6_igmp->ip6_ctlun.ip6_un1.ip6_un1_plen) <= 40)
2130 {
2131 int v = get_int_var_by_name (lexic, "update_ip6_len", 1);
2132 if (v != 0)
2133 {
2134 ip6_igmp->ip6_ctlun.ip6_un1.ip6_un1_plen =
2135 FIX (40 + sizeof (struct igmp6_hdr) + len);
2136 }
2137 }
2138 p = (char *) (pkt + 40);
2139 igmp = (struct igmp6_hdr *) p;
2140
2141 igmp->code = get_int_var_by_name (lexic, "code", 0);
2142 igmp->type = get_int_var_by_name (lexic, "type", 0);
2143 grp = get_str_var_by_name (lexic, "group");
2144
2145 if (grp != NULL)
2146 {
2147 inet_pton (AF_INET6, grp, &igmp->group);
2148 }
2149
2150 igmp->cksum = np_in_cksum ((u_short *) igmp, sizeof (struct igmp6_hdr));
2151 if (data != NULL)
2152 {
2153 char *ptmp = (char *) (pkt + 40 + sizeof (struct igmp6_hdr));
2154 bcopy (ptmp, data, len);
2155 }
2157 retc->x.str_val = (char *) pkt;
2158 retc->size = 40 + sizeof (struct igmp6_hdr) + len;
2159 return retc;
2160 }
2161 else
2162 nasl_perror (lexic, "forge_igmp_v6_packet: missing 'ip6' parameter\n");
2163
2164 return NULL;
2165}
struct in_addr group
unsigned char type
unsigned char code
unsigned short cksum

References alloc_typed_cell(), igmp::cksum, igmp::code, CONST_DATA, FIX, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), igmp::group, len, nasl_perror(), np_in_cksum(), TC::size, TC::str_val, igmp::type, UNFIX, and TC::x.

Here is the call graph for this function:

◆ forge_ip_v6_packet()

tree_cell * forge_ip_v6_packet ( lex_ctxt * lexic)

Forge an IPv6 packet.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]dataData payload
[in]ip6_vVersion. 6 by default.
[in]ip6_tcTraffic class. 0 by default.
[in]ip6_flFlow label. 0 by default.
[in]ip6_pIP protocol. 0 by default.
[in]ip6_hlimHop limit. Max. 255. 64 by default.
[in]ip6_srcSource address.
[in]ip6_dstDestination address.
Returns
Forged IP packet.

Definition at line 119 of file nasl_packet_forgery_v6.c.

120{
121 tree_cell *retc;
122 struct ip6_hdr *pkt;
123 char *s;
124 struct script_infos *script_infos = lexic->script_infos;
125 struct in6_addr *dst_addr;
126 char *data;
127 size_t data_len;
128 int version;
129 int tc;
130 int fl;
131
132 dst_addr = plug_get_host_ip (script_infos);
133
134 if (dst_addr == NULL || (IN6_IS_ADDR_V4MAPPED (dst_addr) == 1))
135 return NULL;
136
137 data = get_str_var_by_name (lexic, "data");
138 data_len = get_var_size_by_name (lexic, "data");
139
141 retc->size = sizeof (struct ip6_hdr) + data_len;
142
143 pkt = (struct ip6_hdr *) g_malloc0 (sizeof (struct ip6_hdr) + data_len);
144 retc->x.str_val = (char *) pkt;
145
146 version = get_int_var_by_name (lexic, "ip6_v", 6);
147 tc = get_int_var_by_name (lexic, "ip6_tc", 0);
148 fl = get_int_var_by_name (lexic, "ip6_fl", 0);
149
150 pkt->ip6_flow = htonl (version << 28 | tc << 20 | fl);
151
152 pkt->ip6_plen = FIX (data_len); /* No extension headers ? */
153 pkt->ip6_nxt = get_int_var_by_name (lexic, "ip6_p", 0);
154 pkt->ip6_hlim = get_int_var_by_name (lexic, "ip6_hlim", 64);
155
156 /* source */
157 s = get_str_var_by_name (lexic, "ip6_src");
158 if (s != NULL)
159 inet_pton (AF_INET6, s, &pkt->ip6_src);
160 /* else this host address? */
161
162 s = get_str_var_by_name (lexic, "ip6_dst");
163 if (s != NULL)
164 inet_pton (AF_INET6, s, &pkt->ip6_dst);
165 else
166 pkt->ip6_dst = *dst_addr;
167
168 if (data != NULL)
169 {
170 bcopy (data, retc->x.str_val + sizeof (struct ip6_hdr), data_len);
171 }
172
173 /*
174 There is no checksum for ipv6. Only upper layer
175 calculates a checksum using pseudoheader
176 */
177 return retc;
178}
struct in6_addr * plug_get_host_ip(struct script_infos *args)
Definition plugutils.c:371
struct script_infos * script_infos

References alloc_typed_cell(), CONST_DATA, FIX, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), plug_get_host_ip(), struct_lex_ctxt::script_infos, TC::size, TC::str_val, and TC::x.

Here is the call graph for this function:

◆ forge_tcp_v6_packet()

tree_cell * forge_tcp_v6_packet ( lex_ctxt * lexic)

Forge TCP packet.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]ip6IPv6 packet.
[in]dataData.
[in]th_sportSource port. 0 by default.
[in]th_dportDestination port. 0 by default.
[in]th_seqSequence number. Random by default.
[in]th_ackAcknowledgement number. 0 by default.
[in]th_x20 by default.
[in]th_offData offset. 5 by default.
[in]th_flagsFlags. 0 by default.
[in]th_winWindow. 0 by default.
[in]th_sumChecksum. Is filled in automatically by default
[in]th_urpUrgent pointer. 0 by default.
Returns
tree_cell with the forged TCP packet containing IPv6 header.

Definition at line 531 of file nasl_packet_forgery_v6.c.

532{
533 tree_cell *retc;
534 char *data;
535 size_t len;
536 struct ip6_hdr *ip6, *tcp_packet;
537 struct tcphdr *tcp;
538 size_t ipsz;
539
540 ip6 = (struct ip6_hdr *) get_str_var_by_name (lexic, "ip6");
541 if (ip6 == NULL)
542 {
543 nasl_perror (lexic,
544 "forge_tcp_v6_packet: You must supply the 'ip6' argument\n");
545 return NULL;
546 }
547
548 ipsz = get_var_size_by_name (lexic, "ip6");
549
550 // Not considering IP Options.
551 if (ipsz != 40)
552 ipsz = 40;
553
554 data = get_str_var_by_name (lexic, "data");
555 len = data == NULL ? 0 : get_var_size_by_name (lexic, "data");
556
558 tcp_packet =
559 (struct ip6_hdr *) g_malloc0 (ipsz + sizeof (struct tcphdr) + len);
560 retc->x.str_val = (char *) tcp_packet;
561
562 bcopy (ip6, tcp_packet, ipsz);
563 /* Adjust length in ipv6 header */
564 tcp_packet->ip6_ctlun.ip6_un1.ip6_un1_plen =
565 FIX (sizeof (struct tcphdr) + len);
566 tcp = (struct tcphdr *) ((char *) tcp_packet + 40);
567
568 tcp->th_sport = ntohs (get_int_var_by_name (lexic, "th_sport", 0));
569 tcp->th_dport = ntohs (get_int_var_by_name (lexic, "th_dport", 0));
570 tcp->th_seq = htonl (get_int_var_by_name (lexic, "th_seq", rand ()));
571 tcp->th_ack = htonl (get_int_var_by_name (lexic, "th_ack", 0));
572 tcp->th_x2 = get_int_var_by_name (lexic, "th_x2", 0);
573 tcp->th_off = get_int_var_by_name (lexic, "th_off", 5);
574 tcp->th_flags = get_int_var_by_name (lexic, "th_flags", 0);
575 tcp->th_win = htons (get_int_var_by_name (lexic, "th_win", 0));
576 tcp->th_sum = get_int_var_by_name (lexic, "th_sum", 0);
577 tcp->th_urp = get_int_var_by_name (lexic, "th_urp", 0);
578
579 if (data != NULL)
580 bcopy (data, (char *) tcp + sizeof (struct tcphdr), len);
581
582 if (!tcp->th_sum)
583 {
584 struct v6pseudohdr pseudoheader;
585 char *tcpsumdata = g_malloc0 (sizeof (struct v6pseudohdr) + len + 1);
586
587 bzero (&pseudoheader, 38 + sizeof (struct tcphdr));
588 memcpy (&pseudoheader.s6addr, &ip6->ip6_src, sizeof (struct in6_addr));
589 memcpy (&pseudoheader.d6addr, &ip6->ip6_dst, sizeof (struct in6_addr));
590
591 pseudoheader.protocol = IPPROTO_TCP;
592 pseudoheader.length = htons (sizeof (struct tcphdr) + len);
593 bcopy ((char *) tcp, (char *) &pseudoheader.tcpheader,
594 sizeof (struct tcphdr));
595 /* fill tcpsumdata with data to checksum */
596 bcopy ((char *) &pseudoheader, tcpsumdata, sizeof (struct v6pseudohdr));
597 if (data != NULL)
598 bcopy ((char *) data, tcpsumdata + sizeof (struct v6pseudohdr), len);
599 tcp->th_sum = np_in_cksum ((unsigned short *) tcpsumdata,
600 38 + sizeof (struct tcphdr) + len);
601 g_free (tcpsumdata);
602 }
603
604 retc->size = ipsz + sizeof (struct tcphdr) + len;
605 return retc;
606}

References alloc_typed_cell(), CONST_DATA, v6pseudohdr::d6addr, FIX, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), len, v6pseudohdr::length, nasl_perror(), np_in_cksum(), v6pseudohdr::protocol, v6pseudohdr::s6addr, TC::size, TC::str_val, v6pseudohdr::tcpheader, and TC::x.

Here is the call graph for this function:

◆ forge_udp_v6_packet()

tree_cell * forge_udp_v6_packet ( lex_ctxt * lexic)

Definition at line 1396 of file nasl_packet_forgery_v6.c.

1397{
1398 tree_cell *retc;
1399 struct ip6_hdr *ip6 = (struct ip6_hdr *) get_str_var_by_name (lexic, "ip6");
1400
1401 if (ip6 != NULL)
1402 {
1403 char *data = get_str_var_by_name (lexic, "data");
1404 size_t data_len = get_var_size_by_name (lexic, "data");
1405 u_char *pkt;
1406 struct ip6_hdr *udp_packet;
1407 struct udphdr *udp;
1408
1409 pkt = g_malloc0 (sizeof (struct udphdr) + 40 + data_len);
1410 udp_packet = (struct ip6_hdr *) pkt;
1411 udp = (struct udphdr *) (pkt + 40);
1412
1413 udp->uh_sum = get_int_var_by_name (lexic, "uh_sum", 0);
1414 bcopy ((char *) ip6, pkt, 40);
1415
1416 udp->uh_sport = htons (get_int_var_by_name (lexic, "uh_sport", 0));
1417 udp->uh_dport = htons (get_int_var_by_name (lexic, "uh_dport", 0));
1418 udp->uh_ulen = htons (get_int_var_by_name (
1419 lexic, "uh_ulen", data_len + sizeof (struct udphdr)));
1420
1421 if (data_len != 0 && data != NULL)
1422 bcopy (data, (pkt + 40 + sizeof (struct udphdr)), data_len);
1423
1424 if (!udp->uh_sum)
1425 {
1427 char *udpsumdata =
1428 g_malloc0 (sizeof (struct v6pseudo_udp_hdr) + data_len + 1);
1429
1430 bzero (&pseudohdr, sizeof (struct v6pseudo_udp_hdr));
1431 memcpy (&pseudohdr.s6addr, &ip6->ip6_src, sizeof (struct in6_addr));
1432 memcpy (&pseudohdr.d6addr, &ip6->ip6_dst, sizeof (struct in6_addr));
1433
1434 pseudohdr.proto = IPPROTO_UDP;
1435 pseudohdr.len = htons (sizeof (struct udphdr) + data_len);
1436 bcopy ((char *) udp, (char *) &pseudohdr.udpheader,
1437 sizeof (struct udphdr));
1438 bcopy ((char *) &pseudohdr, udpsumdata, sizeof (pseudohdr));
1439 if (data != NULL)
1440 {
1441 bcopy ((char *) data, udpsumdata + sizeof (pseudohdr), data_len);
1442 }
1443 udp->uh_sum = np_in_cksum ((unsigned short *) udpsumdata,
1444 38 + sizeof (struct udphdr) + data_len);
1445 g_free (udpsumdata);
1446 }
1447
1448 if (UNFIX (udp_packet->ip6_ctlun.ip6_un1.ip6_un1_plen) <= 40)
1449 {
1450 int v = get_int_var_by_name (lexic, "update_ip6_len", 1);
1451 if (v != 0)
1452 {
1453 udp_packet->ip6_ctlun.ip6_un1.ip6_un1_plen =
1454 FIX (ntohs (udp->uh_ulen));
1455 }
1456 }
1457
1459 retc->x.str_val = (char *) pkt;
1460 retc->size = 8 + 40 + data_len;
1461
1462 return retc;
1463 }
1464 else
1465 nasl_perror (lexic, "forge_udp_v6_packet:'ip6' argument missing. \n");
1466
1467 return NULL;
1468}

References alloc_typed_cell(), CONST_DATA, FIX, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), nasl_perror(), np_in_cksum(), TC::size, TC::str_val, UNFIX, and TC::x.

Here is the call graph for this function:

◆ get_icmp_v6_element()

tree_cell * get_icmp_v6_element ( lex_ctxt * lexic)

Definition at line 1985 of file nasl_packet_forgery_v6.c.

1986{
1987 struct icmp6_hdr *icmp;
1988 char *p;
1989
1990 if ((p = get_str_var_by_name (lexic, "icmp")) != NULL)
1991 {
1992 char *elem = get_str_var_by_name (lexic, "element");
1993 int value;
1994 tree_cell *retc;
1995
1996 icmp = (struct icmp6_hdr *) (p + 40);
1997
1998 if (elem == NULL)
1999 {
2000 nasl_perror (lexic, "%s: Missing 'element' argument\n", __func__);
2001 return NULL;
2002 }
2003
2004 else if (!strcmp (elem, "icmp_code"))
2005 value = icmp->icmp6_code;
2006 else if (!strcmp (elem, "icmp_type"))
2007 value = icmp->icmp6_type;
2008 else if (!strcmp (elem, "icmp_cksum"))
2009 value = ntohs (icmp->icmp6_cksum);
2010 else if (!strcmp (elem, "icmp_id"))
2011 value = ntohs (icmp->icmp6_id);
2012 else if (!strcmp (elem, "icmp_seq"))
2013 value = ntohs (icmp->icmp6_seq);
2014 else if (!strcmp (elem, "data"))
2015 {
2017 retc->size = get_var_size_by_name (lexic, "icmp") - 40 - 8;
2018 if (retc->size > 0)
2019 {
2020 retc->x.str_val = g_malloc0 (retc->size + 1);
2021 memcpy (retc->x.str_val, &(p[40 + 8]), retc->size + 1);
2022 }
2023 else
2024 {
2025 retc->x.str_val = NULL;
2026 retc->size = 0;
2027 }
2028 return retc;
2029 }
2030 else
2031 {
2032 nasl_perror (lexic, "%s: '%s' not a valid 'element' argument\n",
2033 __func__, elem);
2034 return NULL;
2035 }
2036
2037 retc = alloc_typed_cell (CONST_INT);
2038 retc->x.i_val = value;
2039 return retc;
2040 }
2041 else
2042 nasl_perror (lexic, "%s: missing 'icmp' parameter\n", __func__);
2043
2044 return NULL;
2045}
@ CONST_INT
Definition nasl_tree.h:79
long int i_val
Definition nasl_tree.h:104

References alloc_typed_cell(), CONST_DATA, CONST_INT, get_str_var_by_name(), get_var_size_by_name(), TC::i_val, nasl_perror(), TC::size, TC::str_val, and TC::x.

Here is the call graph for this function:

◆ get_ip_v6_element()

tree_cell * get_ip_v6_element ( lex_ctxt * lexic)

Obtain IPv6 header element.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]ipv6IPv6 header. TODO: Once versions older than 20.08 are no longer in use the parameter name can be changed to 'ip6'.
[in]elementElement to extract from the header.
Returns
tree_cell with the IP header element.

Definition at line 191 of file nasl_packet_forgery_v6.c.

192{
193 tree_cell *retc;
194 char *element = get_str_var_by_name (lexic, "element");
195 char ret_ascii[INET6_ADDRSTRLEN];
196 int ret_int = 0;
197 int flag = 0;
198 struct ip6_hdr *ip6;
199
200 /* Parameter name 'ipv6' was renamed to 'ip6' for consistency.
201 * For backwards compatibility reasons we still need to consider the 'ipv6'
202 * argument.
203 */
204 ip6 = (struct ip6_hdr *) get_str_var_by_name (lexic, "ipv6");
205 if (ip6 == NULL)
206 {
207 ip6 = (struct ip6_hdr *) get_str_var_by_name (lexic, "ip6");
208 if (ip6 == NULL)
209 {
210 nasl_perror (lexic, "%s: no valid 'ip6' argument\n", __func__);
211 return NULL;
212 }
213 }
214
215 if (element == NULL)
216 {
217 nasl_perror (lexic, "%s: no valid 'element' argument\n", __func__);
218 return NULL;
219 }
220
221 if (!strcmp (element, "ip6_v"))
222 {
223 ret_int = ntohl (ip6->ip6_flow) >> 28;
224 flag++;
225 }
226 else if (!strcmp (element, "ip6_tc"))
227 {
228 ret_int = (ntohl (ip6->ip6_flow) >> 20) & 0xff;
229 flag++;
230 }
231 else if (!strcmp (element, "ip6_fl"))
232 {
233 ret_int = ntohl (ip6->ip6_flow) & 0x3ffff;
234 flag++;
235 }
236 else if (!strcmp (element, "ip6_plen"))
237 {
238 ret_int = UNFIX (ip6->ip6_plen);
239 flag++;
240 }
241 else if (!strcmp (element, "ip6_nxt"))
242 {
243 ret_int = (ip6->ip6_nxt);
244 flag++;
245 }
246 else if (!strcmp (element, "ip6_hlim"))
247 {
248 ret_int = (ip6->ip6_hlim);
249 flag++;
250 }
251
252 if (flag != 0)
253 {
255 retc->x.i_val = ret_int;
256 return retc;
257 }
258
259 if (!strcmp (element, "ip6_src"))
260 {
261 inet_ntop (AF_INET6, &ip6->ip6_src, ret_ascii, sizeof (ret_ascii));
262 flag++;
263 }
264 else if (!strcmp (element, "ip6_dst"))
265 {
266 inet_ntop (AF_INET6, &ip6->ip6_dst, ret_ascii, sizeof (ret_ascii));
267 flag++;
268 }
269
270 if (flag == 0)
271 {
272 nasl_perror (lexic, "%s : unknown element '%s'\n", __func__, element);
273 return NULL;
274 }
275
277 retc->size = strlen (ret_ascii);
278 retc->x.str_val = g_strdup (ret_ascii);
279
280 return retc;
281}

References alloc_typed_cell(), CONST_DATA, CONST_INT, get_str_var_by_name(), TC::i_val, nasl_perror(), TC::size, TC::str_val, UNFIX, and TC::x.

Here is the call graph for this function:

◆ get_tcp_options()

void get_tcp_options ( char * options,
struct tcp_options * tcp_all_options )
static

Extract all TCP option from an IP datagram.

Parameters
[in]optionsAll options present in the TCP segment.
[out]tcp_all_optionsContainer for the options to return.

Definition at line 707 of file nasl_packet_forgery_v6.c.

708{
709 uint8_t *opt_kind;
710 if (options == NULL)
711 return;
712
713 opt_kind = (uint8_t *) options;
714
715 while (*opt_kind != 0)
716 {
717 switch (*opt_kind)
718 {
719 case TCPOPT_MAXSEG:
720 tcp_all_options->mss.kind = *opt_kind;
721 tcp_all_options->mss.len = *(opt_kind + 1);
722 tcp_all_options->mss.mss = *((uint16_t *) (opt_kind + 2));
723 opt_kind = opt_kind + *(opt_kind + 1);
724 break;
725 case TCPOPT_WINDOW:
726 tcp_all_options->wscale.kind = *opt_kind;
727 tcp_all_options->wscale.len = *(opt_kind + 1);
728 tcp_all_options->wscale.wscale = (uint8_t) * (opt_kind + 2);
729 opt_kind = opt_kind + *(opt_kind + 1);
730 break;
731 case TCPOPT_SACK_PERMITTED:
732 tcp_all_options->sack_perm.kind = *opt_kind;
733 tcp_all_options->sack_perm.len = *(opt_kind + 1);
734 opt_kind = opt_kind + *(opt_kind + 1);
735 break;
736 case TCPOPT_TIMESTAMP:
737 tcp_all_options->tstamp.kind = *opt_kind;
738 tcp_all_options->tstamp.len = *(opt_kind + 1);
739 tcp_all_options->tstamp.tstamp = *((uint32_t *) (opt_kind + 2));
740 tcp_all_options->tstamp.e_tstamp = *((uint32_t *) (opt_kind + 6));
741 opt_kind = opt_kind + *(opt_kind + 1);
742 break;
743 case TCPOPT_EOL:
744 case TCPOPT_NOP:
745 opt_kind++;
746 break;
747 case TCPOPT_SACK: // Not supported
748 opt_kind = opt_kind + *(opt_kind + 1);
749 break;
750 default:
751 g_debug ("%s: Unsupported %u TCP option. "
752 "Not all options are returned.",
753 __func__, *opt_kind);
754 *opt_kind = 0;
755 break;
756 }
757 }
758}

References tcp_opt_tstamp::e_tstamp, tcp_opt_mss::kind, tcp_opt_sack_perm::kind, tcp_opt_tstamp::kind, tcp_opt_wscale::kind, tcp_opt_mss::len, tcp_opt_sack_perm::len, tcp_opt_tstamp::len, tcp_opt_wscale::len, tcp_opt_mss::mss, tcp_options::mss, tcp_options::sack_perm, tcp_opt_tstamp::tstamp, tcp_options::tstamp, tcp_opt_wscale::wscale, and tcp_options::wscale.

Referenced by dump_tcp_v6_packet(), and get_tcp_v6_option().

Here is the caller graph for this function:

◆ get_tcp_v6_element()

tree_cell * get_tcp_v6_element ( lex_ctxt * lexic)

Get TCP Header element.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]tcpIPv6 packet
[in]elementElement to extract from the header (see forge_tcp_v6_packet()).
Returns
tree_cell with the forged IP packet.

Definition at line 619 of file nasl_packet_forgery_v6.c.

620{
621 u_char *packet = (u_char *) get_str_var_by_name (lexic, "tcp");
622 struct ip6_hdr *ip6;
623 long int ipsz;
624 struct tcphdr *tcp;
625 char *element;
626 int ret;
627 tree_cell *retc;
628
629 ipsz = get_var_size_by_name (lexic, "tcp");
630
631 if (packet == NULL)
632 {
633 nasl_perror (lexic, "get_tcp_v6_element: No valid 'tcp' argument\n");
634 return NULL;
635 }
636
637 ip6 = (struct ip6_hdr *) packet;
638
639 /* valid ipv6 header check */
640 if (UNFIX (ip6->ip6_plen) > ipsz)
641 return NULL; /* Invalid packet */
642
643 tcp = (struct tcphdr *) (packet + 40);
644
645 element = get_str_var_by_name (lexic, "element");
646 if (!element)
647 {
648 nasl_perror (lexic, "get_tcp_v6_element: No valid 'element' argument\n");
649 return NULL;
650 }
651
652 if (!strcmp (element, "th_sport"))
653 ret = ntohs (tcp->th_sport);
654 else if (!strcmp (element, "th_dsport"))
655 ret = ntohs (tcp->th_dport);
656 else if (!strcmp (element, "th_seq"))
657 ret = ntohl (tcp->th_seq);
658 else if (!strcmp (element, "th_ack"))
659 ret = ntohl (tcp->th_ack);
660 else if (!strcmp (element, "th_x2"))
661 ret = tcp->th_x2;
662 else if (!strcmp (element, "th_off"))
663 ret = tcp->th_off;
664 else if (!strcmp (element, "th_flags"))
665 ret = tcp->th_flags;
666 else if (!strcmp (element, "th_win"))
667 ret = ntohs (tcp->th_win);
668 else if (!strcmp (element, "th_sum"))
669 ret = tcp->th_sum;
670 else if (!strcmp (element, "th_urp"))
671 ret = tcp->th_urp;
672 else if (!strcmp (element, "data"))
673 {
675 retc->size = UNFIX (ip6->ip6_plen) - tcp->th_off * 4;
676 if (retc->size < 0 || retc->size > ipsz - 40 - tcp->th_off * 4)
677 {
678 nasl_perror (lexic,
679 "get_tcp_v6_element: Erroneous tcp header offset %d\n",
680 retc->size);
681 deref_cell (retc);
682 return NULL;
683 }
684 retc->x.str_val = g_malloc0 (retc->size);
685 bcopy ((char *) tcp + tcp->th_off * 4, retc->x.str_val, retc->size);
686 return retc;
687 }
688 else
689 {
690 nasl_perror (lexic, "get_tcp_v6_element: Unknown tcp field %s\n",
691 element);
692 return NULL;
693 }
694
696 retc->x.i_val = ret;
697 return retc;
698}
void deref_cell(tree_cell *c)
Definition nasl_tree.c:178

References alloc_typed_cell(), CONST_DATA, CONST_INT, deref_cell(), get_str_var_by_name(), get_var_size_by_name(), TC::i_val, nasl_perror(), TC::size, TC::str_val, UNFIX, and TC::x.

Here is the call graph for this function:

◆ get_tcp_v6_option()

tree_cell * get_tcp_v6_option ( lex_ctxt * lexic)

Get a TCP option from an IP datagram if present. Possible options are: TCPOPT_MAXSEG (2), values between 536 and 65535 TCPOPT_WINDOW (3), with values between 0 and 14 TCPOPT_SACK_PERMITTED (4), no value required. TCPOPT_TIMESTAMP (8), 8 bytes value for timestamp and echo timestamp, 4 bytes each one.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]tcpThe full IP datagram (IP + TCP).
[in]optionOption to get.
Returns
Integer or array given the case.

Definition at line 776 of file nasl_packet_forgery_v6.c.

777{
778 u_char *packet = (u_char *) get_str_var_by_name (lexic, "tcp");
779 struct ip6_hdr *ip6;
780 size_t ipsz;
781 struct tcphdr *tcp;
782 char *options;
783 int opt;
784 tree_cell *retc;
785 nasl_array *arr;
787
788 struct tcp_options *tcp_all_options = NULL;
789
790 if (packet == NULL)
791 {
792 nasl_perror (lexic, "%s: No valid 'tcp' argument passed.\n", __func__);
793 return NULL;
794 }
795
796 opt = get_int_var_by_name (lexic, "option", -1);
797 if (opt < 0)
798 {
799 nasl_perror (lexic,
800 "%s: No 'option' argument passed but required.\n."
801 "Usage: %s(tcp:<tcp>, option:<TCPOPT>)",
802 __func__, __func__);
803 return NULL;
804 }
805
806 ip6 = (struct ip6_hdr *) packet;
807
808 /* valid ipv6 header check */
809 ipsz = get_var_size_by_name (lexic, "tcp");
810 if (UNFIX (ip6->ip6_plen) > ipsz)
811 return NULL; /* Invalid packet */
812
813 tcp = (struct tcphdr *) (packet + 40);
814
815 if (tcp->th_off <= 5)
816 return NULL;
817
818 // Get options from the segment
819 options = (char *) g_malloc0 (sizeof (uint8_t) * 4 * (tcp->th_off - 5));
820 memcpy (options, (char *) tcp + 20, (tcp->th_off - 5) * 4);
821
822 tcp_all_options = g_malloc0 (sizeof (struct tcp_options));
823 get_tcp_options (options, tcp_all_options);
824 if (tcp_all_options == NULL)
825 {
826 nasl_perror (lexic, "%s: No TCP options found in passed TCP packet.\n",
827 __func__);
828
829 g_free (options);
830 return NULL;
831 }
832
833 opt = get_int_var_by_name (lexic, "option", -1);
834 retc = NULL;
835 switch (opt)
836 {
837 case TCPOPT_MAXSEG:
839 retc->x.i_val = ntohs ((uint16_t) tcp_all_options->mss.mss);
840 break;
841 case TCPOPT_WINDOW:
843 retc->x.i_val = tcp_all_options->wscale.wscale;
844 break;
845 case TCPOPT_SACK_PERMITTED:
847 retc->x.i_val = tcp_all_options->sack_perm.kind ? 1 : 0;
848 break;
849 case TCPOPT_TIMESTAMP:
851 retc->x.ref_val = arr = g_malloc0 (sizeof (nasl_array));
852
853 memset (&v, 0, sizeof (v));
854 v.var_type = VAR2_INT;
855 v.v.v_int = ntohl ((uint32_t) tcp_all_options->tstamp.tstamp);
856 add_var_to_array (arr, "timestamp", &v);
857
858 memset (&v, 0, sizeof (v));
859 v.var_type = VAR2_INT;
860 v.v.v_int = ntohl ((uint32_t) tcp_all_options->tstamp.e_tstamp);
861 add_var_to_array (arr, "echo_timestamp", &v);
862 break;
863 default:
864 nasl_perror (lexic, "%s: Invalid TCP option passed.\n", __func__);
865 break;
866 }
867
868 g_free (tcp_all_options);
869 g_free (options);
870 return retc;
871}
@ DYN_ARRAY
Definition nasl_tree.h:90
int add_var_to_array(nasl_array *a, char *name, const anon_nasl_var *v)
Definition nasl_var.c:1277
struct st_a_nasl_var anon_nasl_var
struct st_nasl_array nasl_array
@ VAR2_INT
Definition nasl_var.h:16
void * ref_val
Definition nasl_tree.h:105
union st_a_nasl_var::@154137074032032170165360023270032033276061363156 v
long int v_int
Definition nasl_var.h:48

References add_var_to_array(), alloc_typed_cell(), CONST_INT, DYN_ARRAY, tcp_opt_tstamp::e_tstamp, get_int_var_by_name(), get_str_var_by_name(), get_tcp_options(), get_var_size_by_name(), TC::i_val, tcp_opt_sack_perm::kind, tcp_opt_mss::mss, tcp_options::mss, nasl_perror(), TC::ref_val, tcp_options::sack_perm, tcp_opt_tstamp::tstamp, tcp_options::tstamp, UNFIX, st_a_nasl_var::v, st_a_nasl_var::v_int, VAR2_INT, st_a_nasl_var::var_type, tcp_opt_wscale::wscale, tcp_options::wscale, and TC::x.

Here is the call graph for this function:

◆ get_udp_v6_element()

tree_cell * get_udp_v6_element ( lex_ctxt * lexic)

Definition at line 1480 of file nasl_packet_forgery_v6.c.

1481{
1482 tree_cell *retc;
1483 char *udp;
1484 char *element;
1485 size_t ipsz;
1486 struct udphdr *udphdr;
1487 int ret;
1488
1489 udp = get_str_var_by_name (lexic, "udp");
1490 ipsz = get_var_size_by_name (lexic, "udp");
1491
1492 element = get_str_var_by_name (lexic, "element");
1493 if (udp == NULL || element == NULL)
1494 {
1495 nasl_perror (
1496 lexic, "get_udp_v6_element() usage :\n"
1497 "element = get_udp_v6_element(udp:<udp>,element:<element>\n");
1498 return NULL;
1499 }
1500
1501 if (40 + sizeof (struct udphdr) > ipsz)
1502 return NULL;
1503
1504 udphdr = (struct udphdr *) (udp + 40);
1505 if (!strcmp (element, "uh_sport"))
1506 ret = ntohs (udphdr->uh_sport);
1507 else if (!strcmp (element, "uh_dport"))
1508 ret = ntohs (udphdr->uh_dport);
1509 else if (!strcmp (element, "uh_ulen"))
1510 ret = ntohs (udphdr->uh_ulen);
1511 else if (!strcmp (element, "uh_sum"))
1512 ret = ntohs (udphdr->uh_sum);
1513 else if (!strcmp (element, "data"))
1514 {
1515 int sz;
1517 sz = ntohs (udphdr->uh_ulen) - sizeof (struct udphdr);
1518
1519 if (ntohs (udphdr->uh_ulen) - 40 - sizeof (struct udphdr) > ipsz)
1520 sz = ipsz - 40 - sizeof (struct udphdr);
1521
1522 retc->x.str_val = g_malloc0 (sz);
1523 retc->size = sz;
1524 bcopy (udp + 40 + sizeof (struct udphdr), retc->x.str_val, sz);
1525 return retc;
1526 }
1527 else
1528 {
1529 nasl_perror (lexic, "%s is not a value of a udp packet\n", element);
1530 return NULL;
1531 }
1532
1533 retc = alloc_typed_cell (CONST_INT);
1534 retc->x.i_val = ret;
1535 return retc;
1536}

References alloc_typed_cell(), CONST_DATA, CONST_INT, get_str_var_by_name(), get_var_size_by_name(), TC::i_val, nasl_perror(), TC::size, TC::str_val, and TC::x.

Here is the call graph for this function:

◆ insert_ip_v6_options()

tree_cell * insert_ip_v6_options ( lex_ctxt * lexic)

Adds an IPv6 option to the datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]ip6IPv6 packet.
[in]dataData payload.
[in]codeCode of option.
[in]lengthLength of value.
[in]valueValue of the option.
Returns
the modified datagram.

Definition at line 395 of file nasl_packet_forgery_v6.c.

396{
397 struct ip6_hdr *ip6 = (struct ip6_hdr *) get_str_var_by_name (lexic, "ip6");
398 int code = get_int_var_by_name (lexic, "code", 0);
399 int len = get_int_var_by_name (lexic, "length", 0);
400 char *value = get_str_var_by_name (lexic, "value");
401 size_t value_size = get_var_size_by_name (lexic, "value");
402 tree_cell *retc;
403 struct ip6_hdr *new_packet;
404 char *p;
405 size_t size = get_var_size_by_name (lexic, "ip6");
406 u_char uc_code, uc_len;
407 int pad_len;
408 char zero = '0';
409 int i;
410 int pl;
411
412 if (ip6 == NULL)
413 {
414 nasl_perror (lexic,
415 "Usage : %s(ip6:<ip6>, code:<code>, "
416 "length:<len>, value:<value>\n",
417 __func__);
418 return NULL;
419 }
420
421 pad_len = 4 - ((sizeof (uc_code) + sizeof (uc_len) + value_size) % 4);
422 if (pad_len == 4)
423 pad_len = 0;
424
425 pl = 40 < UNFIX (ip6->ip6_plen) ? 40 : UNFIX (ip6->ip6_plen);
426 new_packet = g_malloc0 (size + 4 + value_size + pad_len);
427 bcopy (ip6, new_packet, pl);
428
429 uc_code = (u_char) code;
430 uc_len = (u_char) len;
431
432 p = (char *) new_packet;
433 bcopy (&uc_code, p + pl, sizeof (uc_code));
434 bcopy (&uc_len, p + pl + sizeof (uc_code), sizeof (uc_len));
435 bcopy (value, p + pl + sizeof (uc_code) + sizeof (uc_len), value_size);
436
437 zero = 0;
438 for (i = 0; i < pad_len; i++)
439 {
440 bcopy (&zero,
441 p + pl + sizeof (uc_code) + sizeof (uc_len) + value_size + i, 1);
442 }
443
444 p = (char *) ip6;
445 bcopy (p + pl,
446 new_packet
447 + (sizeof (uc_code) + sizeof (uc_len) + value_size + pad_len) + pl,
448 size - pl);
449
450 new_packet->ip6_plen =
451 FIX (size + sizeof (uc_code) + sizeof (uc_len) + value_size + pad_len);
452
454 retc->size = size + value_size + sizeof (uc_code) + sizeof (uc_len) + pad_len;
455 retc->x.str_val = (char *) new_packet;
456
457 return retc;
458}
#define code
u_char zero

◆ insert_tcp_v6_options()

tree_cell * insert_tcp_v6_options ( lex_ctxt * lexic)

Add options to a TCP segment header. Possible options are: TCPOPT_MAXSEG (2), values between 536 and 65535 TCPOPT_WINDOW (3), with values between 0 and 14 TCPOPT_SACK_PERMITTED (4), no value required. TCPOPT_TIMESTAMP (8), 8 bytes value for timestamp and echo timestamp, 4 bytes each one.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]tcpIP datagram.
[in]data(optional) TCP data payload.
[in]unnamedoption.
[in]Valuefor unnamed option if required.
Returns
The modified IP datagram.

Definition at line 1000 of file nasl_packet_forgery_v6.c.

1001{
1002 char *pkt = get_str_var_by_name (lexic, "tcp");
1003 struct ip6_hdr *ip6 = (struct ip6_hdr *) pkt;
1004 size_t pktsz = get_var_size_by_name (lexic, "tcp");
1005 struct tcphdr *tcp;
1006 tree_cell *retc;
1007 char *data = get_str_var_by_name (lexic, "data");
1008 size_t data_len = get_var_size_by_name (lexic, "data");
1009 char *npkt;
1010 int tcp_opt, tcp_opt_val, tcp_opt_val2;
1011 int current_opt_len, total_opt_len, opt_size_allocated;
1012 char *opts, *ptr_opts_pos;
1013 uint8_t eol, nop;
1014 int i;
1015
1016 struct tcp_opt_mss *opt_mss;
1017 struct tcp_opt_wscale *opt_wscale;
1018 struct tcp_opt_sack_perm *opt_sack_perm;
1019 struct tcp_opt_tstamp *opt_tstamp;
1020
1021 if (pkt == NULL)
1022 {
1023 nasl_perror (
1024 lexic, "set_tcp_v6_elements: Invalid value for the argument 'tcp'\n");
1025 return NULL;
1026 }
1027 opts = g_malloc0 (sizeof (char) * 4);
1028 ptr_opts_pos = opts;
1029 opt_size_allocated = 4; // 4 bytes
1030 total_opt_len = 0;
1031 for (i = 0;; i++)
1032 {
1033 tcp_opt = get_int_var_by_num (lexic, i, -1);
1034 current_opt_len = total_opt_len;
1035
1036 if (tcp_opt == -1)
1037 break;
1038
1039 switch (tcp_opt)
1040 {
1041 case TCPOPT_MAXSEG:
1042 tcp_opt_val = get_int_var_by_num (lexic, i + 1, -1);
1043 i++;
1044 if (tcp_opt_val < (int) TCP_MSS_DESIRED || tcp_opt_val > 65535)
1045 {
1046 nasl_perror (lexic, "%s: Invalid value for TCP option MSS\n",
1047 __func__);
1048 break;
1049 }
1050 opt_mss = g_malloc0 (sizeof (struct tcp_opt_mss));
1051 total_opt_len += TCPOLEN_MAXSEG;
1052 opt_mss->kind = TCPOPT_MAXSEG;
1053 opt_mss->len = TCPOLEN_MAXSEG;
1054 opt_mss->mss = FIX (tcp_opt_val);
1055
1056 // Need reallocated memory because options requires it.
1057 if (total_opt_len > opt_size_allocated)
1058 {
1059 opt_size_allocated = ((total_opt_len / 4) + 1) * 4;
1060 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1061 ptr_opts_pos = opts + current_opt_len;
1062 }
1063
1064 memcpy (ptr_opts_pos, (u_char *) opt_mss,
1065 sizeof (struct tcp_opt_mss));
1066 ptr_opts_pos = ptr_opts_pos + sizeof (struct tcp_opt_mss);
1067 g_free (opt_mss);
1068 break;
1069 case TCPOPT_WINDOW:
1070 tcp_opt_val = get_int_var_by_num (lexic, i + 1, -1);
1071 i++;
1072 if (tcp_opt_val < 0 || tcp_opt_val > 14)
1073 {
1074 nasl_perror (lexic, "%s: Invalid value for TCP option WScale\n",
1075 __func__);
1076 break;
1077 }
1078 opt_wscale = g_malloc0 (sizeof (struct tcp_opt_wscale));
1079 total_opt_len += TCPOLEN_WINDOW;
1080 opt_wscale->kind = TCPOPT_WINDOW;
1081 opt_wscale->len = TCPOLEN_WINDOW;
1082 opt_wscale->wscale = tcp_opt_val;
1083
1084 // Need reallocated memory because options requires it.
1085 if (total_opt_len > opt_size_allocated)
1086 {
1087 opt_size_allocated = ((total_opt_len / 4) + 1) * 4;
1088 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1089 ptr_opts_pos = opts + current_opt_len;
1090 }
1091
1092 memcpy (ptr_opts_pos, (u_char *) opt_wscale,
1093 sizeof (struct tcp_opt_wscale));
1094 ptr_opts_pos = ptr_opts_pos + sizeof (struct tcp_opt_wscale);
1095 g_free (opt_wscale);
1096 break;
1097 case TCPOPT_SACK_PERMITTED:
1098 opt_sack_perm = g_malloc0 (sizeof (struct tcp_opt_sack_perm));
1099 total_opt_len += TCPOLEN_SACK_PERMITTED;
1100 opt_sack_perm->kind = TCPOPT_SACK_PERMITTED;
1101 opt_sack_perm->len = TCPOLEN_SACK_PERMITTED;
1102
1103 // Need reallocated memory because options requires it.
1104 if (total_opt_len > opt_size_allocated)
1105 {
1106 opt_size_allocated = ((total_opt_len / 4) + 1) * 4;
1107 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1108 ptr_opts_pos = opts + current_opt_len;
1109 }
1110
1111 memcpy (ptr_opts_pos, (u_char *) opt_sack_perm,
1112 sizeof (struct tcp_opt_sack_perm));
1113 ptr_opts_pos = ptr_opts_pos + sizeof (struct tcp_opt_sack_perm);
1114 g_free (opt_sack_perm);
1115 break;
1116 case TCPOPT_TIMESTAMP:
1117 tcp_opt_val = get_int_var_by_num (lexic, i + 1, -1);
1118 tcp_opt_val2 = get_int_var_by_num (lexic, i + 2, -1);
1119 i = i + 2;
1120 if (tcp_opt_val < 0)
1121 nasl_perror (lexic, "%s: Invalid value for TCP option Timestamp\n",
1122 __func__);
1123 opt_tstamp = g_malloc0 (sizeof (struct tcp_opt_tstamp));
1124 total_opt_len += TCPOLEN_TIMESTAMP;
1125 opt_tstamp->kind = TCPOPT_TIMESTAMP;
1126 opt_tstamp->len = TCPOLEN_TIMESTAMP;
1127 opt_tstamp->tstamp = htonl (tcp_opt_val);
1128 opt_tstamp->e_tstamp = htonl (tcp_opt_val2);
1129
1130 // Need reallocated memory because options requires it.
1131 if (total_opt_len > opt_size_allocated)
1132 {
1133 opt_size_allocated = ((total_opt_len / 4) + 1) * 4;
1134 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1135 ptr_opts_pos = opts + current_opt_len;
1136 }
1137
1138 memcpy (ptr_opts_pos, (u_char *) opt_tstamp,
1139 sizeof (struct tcp_opt_tstamp));
1140 ptr_opts_pos = ptr_opts_pos + sizeof (struct tcp_opt_tstamp);
1141 g_free (opt_tstamp);
1142 break;
1143 case TCPOPT_NOP:
1144 case TCPOPT_EOL:
1145 case TCPOPT_SACK: /* Experimental, not supported */
1146 default:
1147 nasl_perror (lexic, "%s: TCP option %d not supported\n", __func__,
1148 tcp_opt);
1149 break;
1150 }
1151 }
1152
1153 // Add NOP padding and End Of Option list kinds.
1154 current_opt_len = total_opt_len;
1155 eol = TCPOPT_EOL;
1156 nop = TCPOPT_NOP;
1157 if (total_opt_len % 4 == 0)
1158 {
1159 opt_size_allocated = opt_size_allocated + 4;
1160 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1161 ptr_opts_pos = opts + total_opt_len;
1162 }
1163 if (current_opt_len < opt_size_allocated - 1)
1164 {
1165 // Add NOPs
1166 for (i = current_opt_len; i < opt_size_allocated - 1; i++)
1167 {
1168 memcpy (ptr_opts_pos, &nop, 1);
1169 total_opt_len++;
1170 ptr_opts_pos++;
1171 }
1172 }
1173 // Add EOL
1174 memcpy (ptr_opts_pos, &eol, 1);
1175
1176 tcp = (struct tcphdr *) (pkt + 40);
1177
1178 if (pktsz < UNFIX (ip6->ip6_plen))
1179 {
1180 g_free (opts);
1181 return NULL;
1182 }
1183
1184 if (data_len == 0)
1185 {
1186 data_len = UNFIX (ip6->ip6_plen) - (tcp->th_off * 4);
1187 data = (char *) ((char *) tcp + tcp->th_off * 4);
1188 }
1189
1190 // Alloc enough memory to hold the options
1191 npkt = g_malloc0 (40 + tcp->th_off * 4 + opt_size_allocated + data_len);
1192 memcpy (npkt, pkt, UNFIX (ip6->ip6_plen) + 40);
1193 ip6 = (struct ip6_hdr *) (npkt);
1194 tcp = (struct tcphdr *) (npkt + 40);
1195
1196 // copy options
1197 memcpy ((char *) tcp + tcp->th_off * 4, opts, opt_size_allocated);
1198 tcp->th_off = tcp->th_off + (opt_size_allocated / 4);
1199
1200 memcpy ((char *) tcp + tcp->th_off * 4, data, data_len);
1201
1202 ip6->ip6_plen = FIX (tcp->th_off * 4 + data_len);
1203
1204 struct v6pseudohdr pseudoheader;
1205 char *tcpsumdata =
1206 g_malloc0 (sizeof (struct v6pseudohdr) + opt_size_allocated + data_len + 1);
1207
1208 memset (&pseudoheader, 0, 38 + sizeof (struct tcphdr));
1209 memcpy (&pseudoheader.s6addr, &ip6->ip6_src, sizeof (struct in6_addr));
1210 memcpy (&pseudoheader.d6addr, &ip6->ip6_dst, sizeof (struct in6_addr));
1211
1212 pseudoheader.protocol = IPPROTO_TCP;
1213 pseudoheader.length =
1214 htons (sizeof (struct tcphdr) + opt_size_allocated + data_len);
1215
1216 // Set th_sum to Zero, necessary for the new checksum calculation
1217 tcp->th_sum = 0;
1218
1219 memcpy ((char *) &pseudoheader.tcpheader, (char *) tcp,
1220 sizeof (struct tcphdr));
1221
1222 /* fill tcpsumdata with data to checksum */
1223 memcpy (tcpsumdata, (char *) &pseudoheader, sizeof (struct v6pseudohdr));
1224 memcpy (tcpsumdata + sizeof (struct v6pseudohdr), (char *) opts,
1225 opt_size_allocated);
1226 if (data != NULL)
1227 memcpy (tcpsumdata + sizeof (struct v6pseudohdr) + opt_size_allocated,
1228 (char *) data, data_len);
1229 tcp->th_sum =
1230 np_in_cksum ((unsigned short *) tcpsumdata,
1231 38 + sizeof (struct tcphdr) + opt_size_allocated + data_len);
1232 g_free (opts);
1233 g_free (tcpsumdata);
1234
1236 retc->size = 40 + (tcp->th_off * 4) + data_len;
1237 retc->x.str_val = npkt;
1238 return retc;
1239}
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition nasl_var.c:1094

References alloc_typed_cell(), CONST_DATA, v6pseudohdr::d6addr, tcp_opt_tstamp::e_tstamp, FIX, get_int_var_by_num(), get_str_var_by_name(), get_var_size_by_name(), tcp_opt_mss::kind, tcp_opt_sack_perm::kind, tcp_opt_tstamp::kind, tcp_opt_wscale::kind, tcp_opt_mss::len, tcp_opt_sack_perm::len, tcp_opt_tstamp::len, tcp_opt_wscale::len, v6pseudohdr::length, tcp_opt_mss::mss, nasl_perror(), np_in_cksum(), v6pseudohdr::protocol, v6pseudohdr::s6addr, TC::size, TC::str_val, v6pseudohdr::tcpheader, tcp_opt_tstamp::tstamp, UNFIX, tcp_opt_wscale::wscale, and TC::x.

Here is the call graph for this function:

◆ nasl_send_v6packet()

tree_cell * nasl_send_v6packet ( lex_ctxt * lexic)

Send forged IPv6 Packets.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]...IPv6 packets to send.
[in]lengthLength of each packet by default.
[in]pcap_activeTRUE by default. Otherwise, NASL does not listen for the answers.
[in]pcap_filterBPF filter.
[in]pcap_timeoutCapture timeout. 5 by default.
[in]allow_multicastDefault 0.
Returns
tree_cell with the response to the sent packet.

Definition at line 2324 of file nasl_packet_forgery_v6.c.

2325{
2326 tree_cell *retc = FAKE_CELL;
2327 int bpf = -1;
2328 u_char *answer;
2329 int answer_sz;
2330 struct sockaddr_in6 sockaddr;
2331 char *ip = NULL;
2332 struct ip6_hdr *sip = NULL;
2333 int vi = 0;
2334 ssize_t b = 0;
2335 size_t len = 0;
2336 int soc;
2337 int use_pcap = get_int_var_by_name (lexic, "pcap_active", 1);
2338 int to = get_int_var_by_name (lexic, "pcap_timeout", 5);
2339 char *filter = get_str_var_by_name (lexic, "pcap_filter");
2340 size_t dfl_len = get_int_var_by_name (lexic, "length", -1);
2341 struct script_infos *script_infos = lexic->script_infos;
2342 struct in6_addr *dstip = plug_get_host_ip (script_infos);
2343 int opt_on = 1;
2344 char name[INET6_ADDRSTRLEN];
2345 int allow_multicast = 0;
2346
2347 if (dstip == NULL || (IN6_IS_ADDR_V4MAPPED (dstip) == 1))
2348 return NULL;
2349 soc = socket (AF_INET6, SOCK_RAW, IPPROTO_RAW);
2350 if (soc < 0)
2351 return NULL;
2352
2353 if (setsockopt (soc, IPPROTO_IPV6, IP_HDRINCL, (char *) &opt_on,
2354 sizeof (opt_on))
2355 < 0)
2356 perror ("setsockopt");
2357 while ((ip = get_str_var_by_num (lexic, vi)) != NULL)
2358 {
2359 allow_multicast = get_int_var_by_name (lexic, "allow_multicast", 0);
2360 size_t sz = get_var_size_by_num (lexic, vi);
2361 vi++;
2362
2363 if (sz < sizeof (struct ip6_hdr))
2364 {
2365 nasl_perror (lexic, "send_v6packet: packet is too short\n");
2366 continue;
2367 }
2368
2369 sip = (struct ip6_hdr *) ip;
2370 if (use_pcap != 0 && bpf < 0)
2371 bpf = init_v6_capture_device (sip->ip6_dst, sip->ip6_src, filter);
2372
2373 bzero (&sockaddr, sizeof (struct sockaddr_in6));
2374 sockaddr.sin6_family = AF_INET6;
2375 sockaddr.sin6_addr = sip->ip6_dst;
2376
2377 if (allow_multicast)
2378 {
2379 struct sockaddr_in6 multicast;
2380
2381 if (setsockopt (soc, SOL_SOCKET, SO_BROADCAST, &opt_on,
2382 sizeof (opt_on))
2383 < 0)
2384 perror ("setsockopt ");
2385
2386 bzero (&multicast, sizeof (struct sockaddr_in6));
2387 sockaddr.sin6_family = AF_INET6;
2388 inet_pton (AF_INET6, "ff02::1", &(multicast.sin6_addr));
2389
2390 if (!IN6_ARE_ADDR_EQUAL (&sockaddr.sin6_addr, &multicast.sin6_addr))
2391 allow_multicast = 0;
2392 }
2393
2394 if (dstip != NULL && !IN6_ARE_ADDR_EQUAL (&sockaddr.sin6_addr, dstip)
2395 && !allow_multicast)
2396 {
2397 char txt1[64], txt2[64];
2398 strncpy (
2399 txt1,
2400 inet_ntop (AF_INET6, &sockaddr.sin6_addr, name, INET6_ADDRSTRLEN),
2401 sizeof (txt1));
2402 txt1[sizeof (txt1) - 1] = '\0';
2403 strncpy (txt2, inet_ntop (AF_INET6, dstip, name, INET6_ADDRSTRLEN),
2404 sizeof (txt2));
2405 txt2[sizeof (txt2) - 1] = '\0';
2406 nasl_perror (lexic,
2407 "send_v6packet: malicious or buggy script is trying to "
2408 "send packet to %s instead of designated target %s\n",
2409 txt1, txt2);
2410 if (bpf >= 0)
2411 bpf_close (bpf);
2412 close (soc);
2413 return NULL;
2414 }
2415
2416 if (dfl_len > 0 && dfl_len < sz)
2417 len = dfl_len;
2418 else
2419 len = sz;
2420
2421 b = sendto (soc, (u_char *) ip, len, 0, (struct sockaddr *) &sockaddr,
2422 sizeof (struct sockaddr_in6));
2423 /* if(b < 0) perror("sendto "); */
2424 if (b >= 0 && use_pcap != 0 && bpf >= 0)
2425 {
2426 if (v6_islocalhost (&sip->ip6_dst))
2427 {
2428 answer = (u_char *) capture_next_v6_packet (bpf, to, &answer_sz);
2429 while (
2430 answer != NULL
2431 && (!memcmp (answer, (char *) ip, sizeof (struct ip6_hdr))))
2432 {
2433 g_free (answer);
2434 answer =
2435 (u_char *) capture_next_v6_packet (bpf, to, &answer_sz);
2436 }
2437 }
2438 else
2439 {
2440 answer = (u_char *) capture_next_v6_packet (bpf, to, &answer_sz);
2441 }
2442 if (answer)
2443 {
2445 retc->x.str_val = (char *) answer;
2446 retc->size = answer_sz;
2447 break;
2448 }
2449 }
2450 }
2451 if (bpf >= 0)
2452 bpf_close (bpf);
2453 close (soc);
2454 return retc;
2455}
void bpf_close(int bpf)
Definition bpf_share.c:164
struct ip6_hdr * capture_next_v6_packet(int bpf, int timeout, int *sz)
int init_v6_capture_device(struct in6_addr src, struct in6_addr dest, char *filter)
const char * name
Definition nasl_init.c:440
int v6_islocalhost(struct in6_addr *addr)
Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
Definition pcap.c:234

References alloc_typed_cell(), bpf_close(), capture_next_v6_packet(), CONST_DATA, FAKE_CELL, get_int_var_by_name(), get_str_var_by_name(), get_str_var_by_num(), get_var_size_by_num(), init_v6_capture_device(), len, name, nasl_perror(), plug_get_host_ip(), struct_lex_ctxt::script_infos, TC::size, TC::str_val, v6_islocalhost(), and TC::x.

Here is the call graph for this function:

◆ nasl_tcp_v6_ping()

tree_cell * nasl_tcp_v6_ping ( lex_ctxt * lexic)

Performs TCP Connect to test if host is alive.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]portPort to ping. Internal list of common ports is used as default.
Returns
tree_cell > 0 if host is alive, 0 otherwise.

Definition at line 2178 of file nasl_packet_forgery_v6.c.

2179{
2180 int port;
2181 u_char packet[sizeof (struct ip6_hdr) + sizeof (struct tcphdr)];
2182 int soc;
2183 struct ip6_hdr *ip = (struct ip6_hdr *) packet;
2184 struct tcphdr *tcp = (struct tcphdr *) (packet + sizeof (struct ip6_hdr));
2185 struct script_infos *script_infos = lexic->script_infos;
2186 struct in6_addr *destination = plug_get_host_ip (script_infos);
2187 struct in6_addr source;
2188 struct sockaddr_in6 soca;
2189 int flag = 0;
2190 unsigned int i = 0;
2191 int bpf;
2192 char filter[255];
2193 tree_cell *retc;
2194 int opt = 1;
2195 struct timeval tv;
2196 int len;
2197
2198#define rnd_tcp_port() (rand () % 65535 + 1024)
2199 int sports[] = {0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2200 0, 0, 0, 0, 0, 53, 0, 0, 20, 0, 25, 0, 0, 0};
2201 int ports[] = {139, 135, 445, 80, 22, 515, 23, 21, 6000, 1025,
2202 25, 111, 1028, 9100, 1029, 79, 497, 548, 5000, 1917,
2203 53, 161, 9001, 65535, 443, 113, 993, 8080, 0};
2204 char addr[INET6_ADDRSTRLEN];
2205
2206 if (!destination || (IN6_IS_ADDR_V4MAPPED (destination) == 1))
2207 return NULL;
2208
2209 for (i = 0; i < sizeof (sports) / sizeof (int); i++)
2210 {
2211 if (sports[i] == 0)
2212 sports[i] = rnd_tcp_port ();
2213 }
2214
2215 soc = socket (AF_INET6, SOCK_RAW, IPPROTO_RAW);
2216 if (soc < 0)
2217 return NULL;
2218
2219 if (setsockopt (soc, IPPROTO_IPV6, IP_HDRINCL, (char *) &opt, sizeof (opt))
2220 < 0)
2221 perror ("setsockopt");
2222
2223 port = get_int_var_by_name (lexic, "port", -1);
2224 if (port == -1)
2226 if (v6_islocalhost (destination) > 0)
2227 source = *destination;
2228 else
2229 {
2230 bzero (&source, sizeof (source));
2231 v6_routethrough (destination, &source);
2232 }
2233
2234 snprintf (filter, sizeof (filter), "ip6 and src host %s",
2235 inet_ntop (AF_INET6, destination, addr, sizeof (addr)));
2236 bpf = init_v6_capture_device (*destination, source, filter);
2237
2238 if (v6_islocalhost (destination) != 0)
2239 flag++;
2240 else
2241 {
2242 unsigned int num_ports = sizeof (sports) / sizeof (int);
2243 for (i = 0; i < num_ports && !flag; i++)
2244 {
2245 bzero (packet, sizeof (packet));
2246 /* IPv6 */
2247 int version = 0x60, tc = 0, fl = 0;
2248 ip->ip6_ctlun.ip6_un1.ip6_un1_flow = version | tc | fl;
2249 ip->ip6_nxt = 0x06, ip->ip6_hlim = 0x40, ip->ip6_src = source;
2250 ip->ip6_dst = *destination;
2251 ip->ip6_ctlun.ip6_un1.ip6_un1_plen = FIX (sizeof (struct tcphdr));
2252
2253 /* TCP */
2254 tcp->th_sport = port ? htons (rnd_tcp_port ()) : htons (sports[i]);
2255 tcp->th_flags = TH_SYN;
2256 tcp->th_dport = port ? htons (port) : htons (ports[i]);
2257 tcp->th_seq = rand ();
2258 tcp->th_ack = 0;
2259 tcp->th_x2 = 0;
2260 tcp->th_off = 5;
2261 tcp->th_win = htons (512);
2262 tcp->th_urp = 0;
2263 tcp->th_sum = 0;
2264
2265 /* CKsum */
2266 {
2267 struct v6pseudohdr pseudoheader;
2268
2269 bzero (&pseudoheader, 38 + sizeof (struct tcphdr));
2270 memcpy (&pseudoheader.s6addr, &ip->ip6_src,
2271 sizeof (struct in6_addr));
2272 memcpy (&pseudoheader.d6addr, &ip->ip6_dst,
2273 sizeof (struct in6_addr));
2274
2275 pseudoheader.protocol = IPPROTO_TCP;
2276 pseudoheader.length = htons (sizeof (struct tcphdr));
2277 bcopy ((char *) tcp, (char *) &pseudoheader.tcpheader,
2278 sizeof (struct tcphdr));
2279 tcp->th_sum = np_in_cksum ((unsigned short *) &pseudoheader,
2280 38 + sizeof (struct tcphdr));
2281 }
2282
2283 bzero (&soca, sizeof (soca));
2284 soca.sin6_family = AF_INET6;
2285 soca.sin6_addr = ip->ip6_dst;
2286 if (sendto (soc, (const void *) ip,
2287 sizeof (struct tcphdr) + sizeof (struct ip6_hdr), 0,
2288 (struct sockaddr *) &soca, sizeof (struct sockaddr_in6))
2289 < 0)
2290 {
2291 close (soc);
2292 return NULL;
2293 }
2294 tv.tv_sec = 0;
2295 tv.tv_usec = 100000;
2296 if (bpf >= 0 && bpf_next_tv (bpf, &len, &tv))
2297 flag++;
2298 }
2299 }
2300
2301 retc = alloc_typed_cell (CONST_INT);
2302 retc->x.i_val = flag;
2303 if (bpf >= 0)
2304 bpf_close (bpf);
2305 close (soc);
2306 return retc;
2307}
u_char * bpf_next_tv(int bpf, int *caplen, struct timeval *tv)
Definition bpf_share.c:119
static struct timeval timeval(unsigned long val)
#define rnd_tcp_port()
#define rnd_tcp_port()
char * v6_routethrough(struct in6_addr *dest, struct in6_addr *source)
An awesome function to determine what interface a packet to a given destination should be routed thro...
Definition pcap.c:851
unsigned int plug_get_host_open_port(struct script_infos *desc)
Definition plugutils.c:1328

References alloc_typed_cell(), bpf_close(), bpf_next_tv(), CONST_INT, v6pseudohdr::d6addr, FIX, get_int_var_by_name(), TC::i_val, init_v6_capture_device(), len, v6pseudohdr::length, np_in_cksum(), plug_get_host_ip(), plug_get_host_open_port(), v6pseudohdr::protocol, rnd_tcp_port, v6pseudohdr::s6addr, struct_lex_ctxt::script_infos, v6pseudohdr::tcpheader, timeval(), v6_islocalhost(), v6_routethrough(), and TC::x.

Referenced by nasl_tcp_ping().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ np_in_cksum()

int np_in_cksum ( u_short * p,
int n )
static

Definition at line 74 of file nasl_packet_forgery_v6.c.

77{
78 register u_short answer = 0;
79 register long sum = 0;
80 u_short odd_byte = 0;
81
82 while (n > 1)
83 {
84 sum += *p++;
85 n -= 2;
86 }
87
88 /* mop up an odd byte, if necessary */
89 if (n == 1)
90 {
91 *(u_char *) (&odd_byte) = *(u_char *) p;
92 sum += odd_byte;
93 }
94
95 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
96 sum += (sum >> 16); /* add carry */
97 answer = (int) ~sum; /* ones-complement, truncate */
98 return (answer);
99}

Referenced by forge_icmp_v6_packet(), forge_igmp_v6_packet(), forge_tcp_v6_packet(), forge_udp_v6_packet(), insert_tcp_v6_options(), nasl_tcp_v6_ping(), set_tcp_v6_elements(), and set_udp_v6_elements().

Here is the caller graph for this function:

◆ set_ip_v6_elements()

tree_cell * set_ip_v6_elements ( lex_ctxt * lexic)

Set IPv6 header element.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]ip6IP v6 header.
[in]ip6_plenPayload length.
[in]ip6_hlimHop limit. Max. 255
[in]ip6_nxtNext packet.
[in]ip6_srcSource address
Returns
tree_cell with the forged IP packet.

Definition at line 296 of file nasl_packet_forgery_v6.c.

297{
298 struct ip6_hdr *o_pkt = (struct ip6_hdr *) get_str_var_by_name (lexic, "ip6");
299 size_t size = get_var_size_by_name (lexic, "ip6");
300 tree_cell *retc;
301 struct ip6_hdr *pkt;
302 char *s;
303
304 if (o_pkt == NULL)
305 {
306 nasl_perror (lexic, "%s: missing <ip6> field\n", __func__);
307 return NULL;
308 }
309
310 pkt = (struct ip6_hdr *) g_malloc0 (size);
311 bcopy (o_pkt, pkt, size);
312
313 pkt->ip6_plen = get_int_var_by_name (lexic, "ip6_plen", pkt->ip6_plen);
314 pkt->ip6_nxt = get_int_var_by_name (lexic, "ip6_nxt", pkt->ip6_nxt);
315 pkt->ip6_hlim = get_int_var_by_name (lexic, "ip6_hlim", pkt->ip6_hlim);
316
317 s = get_str_var_by_name (lexic, "ip6_src");
318 if (s != NULL)
319 inet_pton (AF_INET6, s, &pkt->ip6_src);
320
322 retc->size = size;
323 retc->x.str_val = (char *) pkt;
324
325 return retc;
326}

References alloc_typed_cell(), CONST_DATA, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), nasl_perror(), TC::size, TC::str_val, and TC::x.

Here is the call graph for this function:

◆ set_tcp_v6_elements()

tree_cell * set_tcp_v6_elements ( lex_ctxt * lexic)

Set TCP Header element.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]tcpIPv6 packet to modify.
[in]dataData.
[in]th_sportSource port.
[in]th_dportDestination port.
[in]th_seqSequence number.
[in]th_ackAcknowledgement number.
[in]th_x2
[in]th_offData offset.
[in]th_flagsFlags.
[in]th_winWindow.
[in]th_sumChecksum.
[in]th_urpUrgent pointer.
[in]update_ip_lenFlag (TRUE by default). If set, NASL will recompute the size field of the IP datagram.
Returns
tree_cell with the modified IPv6 datagram.

Definition at line 895 of file nasl_packet_forgery_v6.c.

896{
897 char *pkt = get_str_var_by_name (lexic, "tcp");
898 struct ip6_hdr *ip6 = (struct ip6_hdr *) pkt;
899 size_t pktsz = get_var_size_by_name (lexic, "tcp");
900 struct tcphdr *tcp;
901 tree_cell *retc;
902 char *data = get_str_var_by_name (lexic, "data");
903 size_t data_len = get_var_size_by_name (lexic, "data");
904 char *npkt;
905
906 if (pkt == NULL)
907 {
909 lexic, "set_tcp_v6_elements: Invalid value for the argument 'tcp'\n");
910 return NULL;
911 }
912
913 tcp = (struct tcphdr *) (pkt + 40);
914
915 if (pktsz < UNFIX (ip6->ip6_plen))
916 return NULL;
917
918 if (data_len == 0)
919 {
920 data_len = UNFIX (ip6->ip6_plen) - (tcp->th_off * 4);
921 data = (char *) ((char *) tcp + tcp->th_off * 4);
922 }
923
924 npkt = g_malloc0 (40 + tcp->th_off * 4 + data_len);
925 bcopy (pkt, npkt, UNFIX (ip6->ip6_plen) + 40);
926
927 ip6 = (struct ip6_hdr *) (npkt);
928 tcp = (struct tcphdr *) (npkt + 40);
929
930 tcp->th_sport =
931 htons (get_int_var_by_name (lexic, "th_sport", ntohs (tcp->th_sport)));
932 tcp->th_dport =
933 htons (get_int_var_by_name (lexic, "th_dport", ntohs (tcp->th_dport)));
934 tcp->th_seq =
935 htonl (get_int_var_by_name (lexic, "th_seq", ntohl (tcp->th_seq)));
936 tcp->th_ack =
937 htonl (get_int_var_by_name (lexic, "th_ack", ntohl (tcp->th_ack)));
938 tcp->th_x2 = get_int_var_by_name (lexic, "th_x2", tcp->th_x2);
939 tcp->th_off = get_int_var_by_name (lexic, "th_off", tcp->th_off);
940 tcp->th_flags = get_int_var_by_name (lexic, "th_flags", tcp->th_flags);
941 tcp->th_win =
942 htons (get_int_var_by_name (lexic, "th_win", ntohs (tcp->th_win)));
943 tcp->th_sum = get_int_var_by_name (lexic, "th_sum", 0);
944 tcp->th_urp = get_int_var_by_name (lexic, "th_urp", tcp->th_urp);
945
946 bcopy (data, (char *) tcp + tcp->th_off * 4, data_len);
947
948 if (get_int_var_by_name (lexic, "update_ip_len", 1) != 0)
949 {
950 ip6->ip6_plen = FIX (tcp->th_off * 4 + data_len);
951 }
952
953 if (tcp->th_sum == 0)
954 {
955 struct v6pseudohdr pseudoheader;
956 char *tcpsumdata = g_malloc0 (sizeof (struct v6pseudohdr) + data_len + 1);
957
958 bzero (&pseudoheader, 38 + sizeof (struct tcphdr));
959 memcpy (&pseudoheader.s6addr, &ip6->ip6_src, sizeof (struct in6_addr));
960 memcpy (&pseudoheader.d6addr, &ip6->ip6_dst, sizeof (struct in6_addr));
961
962 pseudoheader.protocol = IPPROTO_TCP;
963 pseudoheader.length = htons (sizeof (struct tcphdr) + data_len);
964 bcopy ((char *) tcp, (char *) &pseudoheader.tcpheader,
965 sizeof (struct tcphdr));
966 /* fill tcpsumdata with data to checksum */
967 bcopy ((char *) &pseudoheader, tcpsumdata, sizeof (struct v6pseudohdr));
968 if (data != NULL)
969 bcopy ((char *) data, tcpsumdata + sizeof (struct v6pseudohdr),
970 data_len);
971 tcp->th_sum = np_in_cksum ((unsigned short *) tcpsumdata,
972 38 + sizeof (struct tcphdr) + data_len);
973 g_free (tcpsumdata);
974 }
975
977 retc->size = 40 + (tcp->th_off * 4) + data_len;
978 retc->x.str_val = npkt;
979 return retc;
980}

References alloc_typed_cell(), CONST_DATA, v6pseudohdr::d6addr, FIX, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), v6pseudohdr::length, nasl_perror(), np_in_cksum(), v6pseudohdr::protocol, v6pseudohdr::s6addr, TC::size, TC::str_val, v6pseudohdr::tcpheader, UNFIX, and TC::x.

Here is the call graph for this function:

◆ set_udp_v6_elements()

tree_cell * set_udp_v6_elements ( lex_ctxt * lexic)

Definition at line 1552 of file nasl_packet_forgery_v6.c.

1553{
1554 struct ip6_hdr *ip6 = (struct ip6_hdr *) get_str_var_by_name (lexic, "udp");
1555 size_t sz = get_var_size_by_name (lexic, "udp");
1556 char *data = get_str_var_by_name (lexic, "data");
1557 size_t data_len = get_var_size_by_name (lexic, "data");
1558
1559 if (ip6 != NULL)
1560 {
1561 char *pkt;
1562 struct udphdr *udp;
1563 tree_cell *retc;
1564 int old_len;
1565
1566 if (40 + sizeof (struct udphdr) > sz)
1567 {
1568 return NULL;
1569 }
1570 if (data != NULL)
1571 {
1572 sz = 40 + sizeof (struct udphdr) + data_len;
1573 pkt = g_malloc0 (sz);
1574 bcopy (ip6, pkt, 40 + sizeof (struct udphdr));
1575 }
1576 else
1577 {
1578 pkt = g_malloc0 (sz);
1579 bcopy (ip6, pkt, sz);
1580 }
1581
1582 ip6 = (struct ip6_hdr *) pkt;
1583 if (data != NULL)
1584 {
1585 ip6->ip6_ctlun.ip6_un1.ip6_un1_plen = FIX (sz - 40);
1586 }
1587 udp = (struct udphdr *) (pkt + 40);
1588
1589 udp->uh_sport =
1590 htons (get_int_var_by_name (lexic, "uh_sport", ntohs (udp->uh_sport)));
1591 udp->uh_dport =
1592 htons (get_int_var_by_name (lexic, "uh_dport", ntohs (udp->uh_dport)));
1593
1594 old_len = ntohs (udp->uh_ulen);
1595 udp->uh_ulen =
1596 htons (get_int_var_by_name (lexic, "uh_ulen", ntohs (udp->uh_ulen)));
1597 udp->uh_sum = get_int_var_by_name (lexic, "uh_sum", 0);
1598
1599 if (data != NULL)
1600 {
1601 bcopy (data, pkt + 40 + sizeof (struct udphdr), data_len);
1602 udp->uh_ulen = htons (sizeof (struct udphdr) + data_len);
1603 }
1604
1605 if (!udp->uh_sum)
1606 {
1608 int len = old_len - sizeof (struct udphdr);
1609 char *udpsumdata;
1610 char *ptr = NULL;
1611
1612 if (data != NULL)
1613 {
1614 len = data_len;
1615 }
1616
1617 if (len > 0)
1618 {
1619 ptr = (char *) udp + sizeof (struct udphdr);
1620 }
1621
1622 udpsumdata = g_malloc0 (sizeof (struct v6pseudo_udp_hdr) + len + 1);
1623 bzero (&pseudohdr, sizeof (struct v6pseudo_udp_hdr));
1624
1625 pseudohdr.proto = IPPROTO_UDP;
1626 pseudohdr.len = htons (sizeof (struct udphdr) + data_len);
1627 bcopy ((char *) udp, (char *) &pseudohdr.udpheader,
1628 sizeof (struct udphdr));
1629 memcpy (&pseudohdr.s6addr, &ip6->ip6_src, sizeof (struct in6_addr));
1630 memcpy (&pseudohdr.d6addr, &ip6->ip6_dst, sizeof (struct in6_addr));
1631 bcopy ((char *) &pseudohdr, udpsumdata, sizeof (pseudohdr));
1632 if (ptr != NULL)
1633 {
1634 bcopy ((char *) ptr, udpsumdata + sizeof (pseudohdr), data_len);
1635 }
1636 udp->uh_sum = np_in_cksum ((unsigned short *) udpsumdata,
1637 38 + sizeof (struct udphdr)
1638 + ((len % 2) ? len + 1 : len));
1639 g_free (udpsumdata);
1640 }
1642 retc->size = sz;
1643 retc->x.str_val = pkt;
1644 return retc;
1645 }
1646 else
1647 nasl_perror (lexic,
1648 "set_udp_v6_elements: You must supply the 'udp' argument !\n");
1649
1650 return NULL;
1651}

References alloc_typed_cell(), CONST_DATA, FIX, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), len, nasl_perror(), np_in_cksum(), TC::size, TC::str_val, and TC::x.

Here is the call graph for this function:

Variable Documentation

◆ __attribute__

struct v6pseudo_udp_hdr __attribute__

◆ d6addr

struct in6_addr d6addr

Definition at line 1 of file nasl_packet_forgery_v6.c.

◆ e_tstamp

uint32_t e_tstamp

Definition at line 3 of file nasl_packet_forgery_v6.c.

◆ kind

uint8_t kind

Definition at line 0 of file nasl_packet_forgery_v6.c.

◆ len

uint8_t len

Definition at line 1 of file nasl_packet_forgery_v6.c.

◆ length

u_short length

Definition at line 2 of file nasl_packet_forgery_v6.c.

◆ mss

struct tcp_opt_mss mss

Definition at line 2 of file nasl_packet_forgery_v6.c.

◆ protocol

u_char protocol

Definition at line 6 of file nasl_packet_forgery_v6.c.

◆ s6addr

struct in6_addr s6addr

Definition at line 0 of file nasl_packet_forgery_v6.c.

Referenced by v6_getinterfaces().

◆ sack_perm

struct tcp_opt_sack_perm sack_perm

Definition at line 2 of file nasl_packet_forgery_v6.c.

◆ tcpheader

struct tcphdr tcpheader

Definition at line 7 of file nasl_packet_forgery_v6.c.

◆ tstamp

struct tcp_opt_tstamp tstamp

Definition at line 2 of file nasl_packet_forgery_v6.c.

◆ wscale

struct tcp_opt_wscale wscale

Definition at line 2 of file nasl_packet_forgery_v6.c.

◆ zero1

u_char zero1

Definition at line 3 of file nasl_packet_forgery_v6.c.

◆ zero2

u_char zero2

Definition at line 4 of file nasl_packet_forgery_v6.c.

◆ zero3

u_char zero3

Definition at line 5 of file nasl_packet_forgery_v6.c.