OpenVAS Scanner 23.32.3
nasl_packet_forgery.h File Reference
#include "nasl_lex_ctxt.h"
Include dependency graph for nasl_packet_forgery.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

tree_cellforge_ip_packet (lex_ctxt *)
 Forge an IP datagram.
tree_cellset_ip_elements (lex_ctxt *)
 Modify the fields of a datagram.
tree_cellget_ip_element (lex_ctxt *)
 Extracts a field from an IP datagram.
tree_celldump_ip_packet (lex_ctxt *)
 Dump IP datagrams.
tree_cellinsert_ip_options (lex_ctxt *)
 Add option datagram.
tree_cellforge_tcp_packet (lex_ctxt *)
 Fills an IP datagram with TCP data. Note that the ip_p field is not updated. It returns the modified IP datagram. Its arguments are:
tree_cellget_tcp_element (lex_ctxt *)
 Extracts TCP field from an IP datagram.
tree_cellget_tcp_option (lex_ctxt *)
 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_elements (lex_ctxt *)
 Modify the TCP fields of a datagram.
tree_cellinsert_tcp_options (lex_ctxt *)
 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_packet (lex_ctxt *)
 Dump the TCP part of a IP Datagram.
tree_cellforge_udp_packet (lex_ctxt *)
 Fills an IP datagram with UDP data. Note that the ip_p field is not updated. It returns the modified IP datagram. Its arguments are:
tree_cellset_udp_elements (lex_ctxt *)
 Modify UDP fields of an IP datagram.
tree_celldump_udp_packet (lex_ctxt *)
 Dump the UDP part of a IP Datagram.
tree_cellget_udp_element (lex_ctxt *)
 Get an UDP element from a IP datagram.
tree_cellforge_icmp_packet (lex_ctxt *)
 Fill an IP datagram with ICMP data.
tree_cellget_icmp_element (lex_ctxt *)
 Get an ICMP element from a IP datagram.
tree_celldump_icmp_packet (lex_ctxt *)
 Dump the ICMP part of a IP Datagram.
tree_cellforge_igmp_packet (lex_ctxt *)
 Fills an IP datagram with IGMP data.
tree_cellnasl_tcp_ping (lex_ctxt *)
 Launches a “TCP ping” against the target host.
tree_cellnasl_send_packet (lex_ctxt *)
 Send a list of packets (passed as unnamed arguments) and listens to the answers. It returns a block made of all the sniffed “answers”.
tree_cellnasl_pcap_next (lex_ctxt *)
 Listen to one packet and return it.
tree_cellnasl_send_capture (lex_ctxt *)
 Send a capture.

Function Documentation

◆ dump_icmp_packet()

tree_cell * dump_icmp_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 1928 of file nasl_packet_forgery.c.

1929{
1930 int i = 0;
1931 u_char *pkt;
1932 while ((pkt = (u_char *) get_str_var_by_num (lexic, i++)) != NULL)
1933 {
1934 struct ip *ip = (struct ip *) pkt;
1935 struct icmp *icmp;
1936 icmp = (struct icmp *) (pkt + ip->ip_hl * 4);
1937 printf ("------\n");
1938 printf ("\ticmp_id : %d\n", ntohs (icmp->icmp_id));
1939 printf ("\ticmp_code : %d\n", icmp->icmp_code);
1940 printf ("\ticmp_type : %u\n", icmp->icmp_type);
1941 printf ("\ticmp_seq : %u\n", ntohs (icmp->icmp_seq));
1942 printf ("\ticmp_cksum : %d\n", ntohs (icmp->icmp_cksum));
1943 printf ("\tData : %s\n", icmp->icmp_data);
1944 printf ("\n");
1945 }
1946 return NULL;
1947}
char * get_str_var_by_num(lex_ctxt *, int)
Definition nasl_var.c:1108

References get_str_var_by_num().

Here is the call graph for this function:

◆ dump_ip_packet()

tree_cell * dump_ip_packet ( lex_ctxt * lexic)

Dump IP datagrams.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]...IP datagrams to dump.

Definition at line 434 of file nasl_packet_forgery.c.

435{
436 int i;
437
438 for (i = 0;; i++)
439 {
440 struct ip *ip = (struct ip *) get_str_var_by_num (lexic, i);
441 if (ip == NULL)
442 break;
443 else
444 {
445 printf ("------\n");
446 printf ("\tip_hl : %d\n", ip->ip_hl);
447 printf ("\tip_v : %d\n", ip->ip_v);
448 printf ("\tip_tos : %d\n", ip->ip_tos);
449 printf ("\tip_len : %d\n", UNFIX (ip->ip_len));
450 printf ("\tip_id : %d\n", ntohs (ip->ip_id));
451 printf ("\tip_off : %d\n", UNFIX (ip->ip_off));
452 printf ("\tip_ttl : %d\n", ip->ip_ttl);
453 switch (ip->ip_p)
454 {
455 case IPPROTO_TCP:
456 printf ("\tip_p : IPPROTO_TCP (%d)\n", ip->ip_p);
457 break;
458 case IPPROTO_UDP:
459 printf ("\tip_p : IPPROTO_UDP (%d)\n", ip->ip_p);
460 break;
461 case IPPROTO_ICMP:
462 printf ("\tip_p : IPPROTO_ICMP (%d)\n", ip->ip_p);
463 break;
464 default:
465 printf ("\tip_p : %d\n", ip->ip_p);
466 break;
467 }
468 printf ("\tip_sum : 0x%x\n", ntohs (ip->ip_sum));
469 printf ("\tip_src : %s\n", inet_ntoa (ip->ip_src));
470 printf ("\tip_dst : %s\n", inet_ntoa (ip->ip_dst));
471 printf ("\n");
472 }
473 }
474
475 return FAKE_CELL;
476}
#define UNFIX(n)
#define FAKE_CELL
Definition nasl_tree.h:110

◆ dump_tcp_packet()

tree_cell * dump_tcp_packet ( lex_ctxt * lexic)

Dump the TCP part of a IP Datagram.

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

Definition at line 1304 of file nasl_packet_forgery.c.

1305{
1306 int i = 0;
1307 u_char *pkt;
1308 while ((pkt = (u_char *) get_str_var_by_num (lexic, i++)) != NULL)
1309 {
1310 int a = 0;
1311 struct ip *ip = (struct ip *) pkt;
1312 struct tcphdr *tcp = (struct tcphdr *) (pkt + ip->ip_hl * 4);
1313 unsigned int j;
1314 unsigned int limit;
1315 char *c;
1316 limit = get_var_size_by_num (lexic, i - 1);
1317 printf ("------\n");
1318 printf ("\tth_sport : %d\n", ntohs (tcp->th_sport));
1319 printf ("\tth_dport : %d\n", ntohs (tcp->th_dport));
1320 printf ("\tth_seq : %u\n", (unsigned int) ntohl (tcp->th_seq));
1321 printf ("\tth_ack : %u\n", (unsigned int) ntohl (tcp->th_ack));
1322 printf ("\tth_x2 : %d\n", tcp->th_x2);
1323 printf ("\tth_off : %d\n", tcp->th_off);
1324 printf ("\tth_flags : ");
1325 if (tcp->th_flags & TH_FIN)
1326 {
1327 printf ("TH_FIN");
1328 a++;
1329 }
1330 if (tcp->th_flags & TH_SYN)
1331 {
1332 if (a)
1333 printf ("|");
1334 printf ("TH_SYN");
1335 a++;
1336 }
1337 if (tcp->th_flags & TH_RST)
1338 {
1339 if (a)
1340 printf ("|");
1341 printf ("TH_RST");
1342 a++;
1343 }
1344 if (tcp->th_flags & TH_PUSH)
1345 {
1346 if (a)
1347 printf ("|");
1348 printf ("TH_PUSH");
1349 a++;
1350 }
1351 if (tcp->th_flags & TH_ACK)
1352 {
1353 if (a)
1354 printf ("|");
1355 printf ("TH_ACK");
1356 a++;
1357 }
1358 if (tcp->th_flags & TH_URG)
1359 {
1360 if (a)
1361 printf ("|");
1362 printf ("TH_URG");
1363 a++;
1364 }
1365 if (!a)
1366 printf ("0");
1367 else
1368 printf (" (%d)", tcp->th_flags);
1369 printf ("\n");
1370 printf ("\tth_win : %d\n", ntohs (tcp->th_win));
1371 printf ("\tth_sum : 0x%x\n", ntohs (tcp->th_sum));
1372 printf ("\tth_urp : %d\n", ntohs (tcp->th_urp));
1373
1374 if (tcp->th_off > 5) // Options present
1375 {
1376 char *options;
1377 struct tcp_options *tcp_all_options;
1378
1379 options =
1380 (char *) g_malloc0 (sizeof (uint8_t) * 4 * (tcp->th_off - 5));
1381 memcpy (options, (char *) tcp + 20, (tcp->th_off - 5) * 4);
1382
1383 tcp_all_options = g_malloc0 (sizeof (struct tcp_options));
1384 get_tcp_options (options, tcp_all_options);
1385 if (tcp_all_options != NULL)
1386 {
1387 printf ("\tTCP Options:\n");
1388 printf ("\t\tTCPOPT_MAXSEG: %u\n",
1389 ntohs ((uint16_t) tcp_all_options->mss.mss));
1390 printf ("\t\tTCPOPT_WINDOW: %u\n",
1391 tcp_all_options->wscale.wscale);
1392 printf ("\t\tTCPOPT_SACK_PERMITTED: %u\n",
1393 tcp_all_options->sack_perm.kind ? 1 : 0);
1394 printf ("\t\tTCPOPT_TIMESTAMP TSval: %u\n",
1395 ntohl ((uint32_t) tcp_all_options->tstamp.tstamp));
1396 printf ("\t\tTCPOPT_TIMESTAMP TSecr: %u\n",
1397 ntohl ((uint32_t) tcp_all_options->tstamp.e_tstamp));
1398 }
1399 g_free (options);
1400 g_free (tcp_all_options);
1401 }
1402
1403 printf ("\n\tData : ");
1404 c = (char *) ((char *) tcp + sizeof (struct tcphdr)
1405 + sizeof (uint8_t) * 4 * (tcp->th_off - 5));
1406 if (UNFIX (ip->ip_len) > (sizeof (struct ip) + sizeof (struct tcphdr)))
1407 for (j = 0; j < UNFIX (ip->ip_len) - sizeof (struct ip)
1408 - sizeof (struct tcphdr)
1409 - sizeof (uint8_t) * 4 * (tcp->th_off - 5)
1410 && j < limit;
1411 j++)
1412 printf ("%c", isprint (c[j]) ? c[j] : '.');
1413 printf ("\n");
1414
1415 printf ("\n");
1416 }
1417 return NULL;
1418}
int get_var_size_by_num(lex_ctxt *, int)
Definition nasl_var.c:1145
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_packet()

tree_cell * dump_udp_packet ( lex_ctxt * lexic)

Dump the UDP part of a IP Datagram.

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

Definition at line 1732 of file nasl_packet_forgery.c.

1733{
1734 int i = 0;
1735 u_char *pkt;
1736 while ((pkt = (u_char *) get_str_var_by_num (lexic, i++)) != NULL)
1737 {
1738 struct udphdr *udp = (struct udphdr *) (pkt + sizeof (struct ip));
1739 unsigned int j;
1740 char *c;
1741 unsigned int limit = get_var_size_by_num (lexic, i - 1);
1742 printf ("------\n");
1743 printf ("\tuh_sport : %d\n", ntohs (udp->uh_sport));
1744 printf ("\tuh_dport : %d\n", ntohs (udp->uh_dport));
1745 printf ("\tuh_sum : 0x%x\n", udp->uh_sum);
1746 printf ("\tuh_ulen : %d\n", ntohs (udp->uh_ulen));
1747 printf ("\tdata : ");
1748 c = (char *) udp;
1749 if (udp->uh_ulen > sizeof (struct udphdr))
1750 for (j = sizeof (struct udphdr);
1751 j < (ntohs (udp->uh_ulen)) && j < limit; j++)
1752 printf ("%c", isprint (c[j]) ? c[j] : '.');
1753
1754 printf ("\n");
1755 }
1756 return NULL;
1757}

References get_str_var_by_num(), and get_var_size_by_num().

Here is the call graph for this function:

◆ forge_icmp_packet()

tree_cell * forge_icmp_packet ( lex_ctxt * lexic)

Fill an IP datagram with ICMP data.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]ipIP datagram that is updated.
[in]dataPayload.
[in]icmp_cksumChecksum, computed by default.
[in]icmp_codeICMP code. 0 by default.
[in]icmp_idICMP ID. 0 by default.
[in]icmp_seqICMP sequence number.
[in]icmp_typeICMP type. 0 by default.
[in]update_ip_lenFlag (TRUE by default). If set, NASL will recompute the size field of the IP datagram.
Returns
Modified IP datagram.

Definition at line 1778 of file nasl_packet_forgery.c.

1779{
1780 tree_cell *retc = NULL;
1781 struct ip *ip;
1782 struct ip *ip_icmp;
1783 int ip_sz;
1784 struct icmp *icmp;
1785 char *data, *p;
1786 int len;
1787 u_char *pkt;
1788 int t;
1789
1790 ip = (struct ip *) get_str_var_by_name (lexic, "ip");
1791 ip_sz = get_var_size_by_name (lexic, "ip");
1792 if (ip != NULL)
1793 {
1794 data = get_str_var_by_name (lexic, "data");
1795 len = data == NULL ? 0 : get_var_size_by_name (lexic, "data");
1796
1797 t = get_int_var_by_name (lexic, "icmp_type", 0);
1798 if (t == 13 || t == 14)
1799 len += 3 * sizeof (time_t);
1800
1801 if (ip->ip_hl * 4 > ip_sz)
1802 return NULL;
1803
1804 pkt = g_malloc0 (sizeof (struct icmp) + ip_sz + len);
1805 ip_icmp = (struct ip *) pkt;
1806
1807 bcopy (ip, ip_icmp, ip_sz);
1808 if (UNFIX (ip_icmp->ip_len) <= (ip_icmp->ip_hl * 4))
1809 {
1810 if (get_int_var_by_name (lexic, "update_ip_len", 1) != 0)
1811 {
1812 ip_icmp->ip_len = FIX (ip->ip_hl * 4 + 8 + len);
1813 ip_icmp->ip_sum = 0;
1814 ip_icmp->ip_sum =
1815 np_in_cksum ((u_short *) ip_icmp, ip->ip_hl * 4);
1816 }
1817 }
1818 p = (char *) (pkt + (ip->ip_hl * 4));
1819 icmp = (struct icmp *) p;
1820
1821 icmp->icmp_code = get_int_var_by_name (lexic, "icmp_code", 0);
1822 icmp->icmp_type = t;
1823 icmp->icmp_seq = htons (get_int_var_by_name (lexic, "icmp_seq", 0));
1824 icmp->icmp_id = htons (get_int_var_by_name (lexic, "icmp_id", 0));
1825
1826 if (data != NULL)
1827 bcopy (data, &(p[8]), len);
1828
1829 if (get_int_var_by_name (lexic, "icmp_cksum", -1) == -1)
1830 icmp->icmp_cksum = np_in_cksum ((u_short *) icmp, len + 8);
1831 else
1832 icmp->icmp_cksum = htons (get_int_var_by_name (lexic, "icmp_cksum", 0));
1833
1835 retc->x.str_val = (char *) pkt;
1836 retc->size = ip_sz + len + 8;
1837 }
1838 else
1839 nasl_perror (lexic, "forge_icmp_packet: missing 'ip' parameter\n");
1840
1841 return retc;
1842}
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition nasl_debug.c:105
int get_var_size_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1138
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
#define FIX(n)
static int np_in_cksum(u_short *p, int n)
uint8_t len
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ CONST_DATA
Definition nasl_tree.h:82
struct TC tree_cell
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_packet()

tree_cell * forge_igmp_packet ( lex_ctxt * lexic)

Fills an IP datagram with IGMP data.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]ipIP datagram that is updated.
[in]code0 by default.
[in]data
[in]group
[in]type0 by default.
[in]update_ip_lenFlag (TRUE by default). If set, NASL will recompute the size field of the IP datagram.
Returns
Modified IP datagram.

Definition at line 1974 of file nasl_packet_forgery.c.

1975{
1976 struct ip *ip = (struct ip *) get_str_var_by_name (lexic, "ip");
1977
1978 if (ip != NULL)
1979 {
1980 char *data = get_str_var_by_name (lexic, "data");
1981 int len = data ? get_var_size_by_name (lexic, "data") : 0;
1982 u_char *pkt = g_malloc0 (sizeof (struct igmp) + ip->ip_hl * 4 + len);
1983 struct ip *ip_igmp = (struct ip *) pkt;
1984 struct igmp *igmp;
1985 char *p;
1986 char *grp;
1987 tree_cell *retc;
1988 int ipsz = get_var_size_by_name (lexic, "ip");
1989
1990 bcopy (ip, ip_igmp, ipsz);
1991
1992 if (UNFIX (ip_igmp->ip_len) <= ip_igmp->ip_hl * 4)
1993 {
1994 int v = get_int_var_by_name (lexic, "update_ip_len", 1);
1995 if (v != 0)
1996 {
1997 ip_igmp->ip_len =
1998 FIX (ip->ip_hl * 4 + sizeof (struct igmp) + len);
1999 ip_igmp->ip_sum = 0;
2000 ip_igmp->ip_sum =
2001 np_in_cksum ((u_short *) ip_igmp, ip->ip_hl * 4);
2002 }
2003 }
2004 p = (char *) (pkt + ip_igmp->ip_hl * 4);
2005 igmp = (struct igmp *) p;
2006
2007 igmp->code = get_int_var_by_name (lexic, "code", 0);
2008 igmp->type = get_int_var_by_name (lexic, "type", 0);
2009 grp = get_str_var_by_name (lexic, "group");
2010
2011 if (grp != NULL)
2012 {
2013 inet_aton (grp, &igmp->group);
2014 }
2015
2016 igmp->cksum = np_in_cksum ((u_short *) igmp, sizeof (struct igmp));
2017 if (data != NULL)
2018 {
2019 char *ptmp = (char *) (pkt + ip->ip_hl * 4 + sizeof (struct igmp));
2020 bcopy (ptmp, data, len);
2021 }
2023 retc->x.str_val = (char *) pkt;
2024 retc->size = ip->ip_hl * 4 + sizeof (struct igmp) + len;
2025 return retc;
2026 }
2027 else
2028 nasl_perror (lexic, "forge_igmp_packet: missing 'ip' parameter\n");
2029
2030 return NULL;
2031}
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_packet()

tree_cell * forge_ip_packet ( lex_ctxt * lexic)

Forge an IP datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]dataPayload.
[in]ip_hlIP header length in 32 bits words. 5 by default.
[in]ip_idDatagram ID. Random by default.
[in]ip_lenLength of the datagram. 20 plus the length of the data field by default.
[in]ip_offFragment offset in 64 bits words. 0 by default.
[in]ip_pIP protocol. 0 by default.
[in]ip_srcSource address in ASCII. NASL will convert it into an integer in network order.
[in]ip_dstDestination address in ASCII. NASL will convert it into an integer in network order. Uses the target ip of the current plugin by default.
[in]ip_sumPacket header checksum. It will be computed by default.
[in]ip_tosType of service field. 0 by default
[in]ip_ttlTime To Live field. 64 by default.
[in]ip_vIP version. 4 by default.
Returns
The forged IP packet.

Definition at line 104 of file nasl_packet_forgery.c.

105{
106 tree_cell *retc;
107 struct ip *pkt;
108 char *s;
109 struct script_infos *script_infos = lexic->script_infos;
110 struct in6_addr *dst_addr;
111 char *data;
112 int data_len;
113
114 dst_addr = plug_get_host_ip (script_infos);
115
116 if (dst_addr == NULL || (IN6_IS_ADDR_V4MAPPED (dst_addr) != 1))
117 {
118 nasl_perror (lexic, "forge_ip_packet: No valid dst_addr could be "
119 "determined via call to plug_get_host_ip().\n");
120 return NULL;
121 }
122
123 data = get_str_var_by_name (lexic, "data");
124 data_len = get_var_size_by_name (lexic, "data");
125
127 retc->size = sizeof (struct ip) + data_len;
128
129 pkt = (struct ip *) g_malloc0 (sizeof (struct ip) + data_len);
130 retc->x.str_val = (char *) pkt;
131
132 pkt->ip_hl = get_int_var_by_name (lexic, "ip_hl", 5);
133 pkt->ip_v = get_int_var_by_name (lexic, "ip_v", 4);
134 pkt->ip_tos = get_int_var_by_name (lexic, "ip_tos", 0);
135 /* pkt->ip_len = FIX(get_int_var_by_name(lexic, "ip_len", 20 + data_len)); */
136
137 pkt->ip_len = FIX (20 + data_len);
138
139 pkt->ip_id = htons (get_int_var_by_name (lexic, "ip_id", rand ()));
140 pkt->ip_off = get_int_var_by_name (lexic, "ip_off", 0);
141 pkt->ip_off = FIX (pkt->ip_off);
142 pkt->ip_ttl = get_int_var_by_name (lexic, "ip_ttl", 64);
143 pkt->ip_p = get_int_var_by_name (lexic, "ip_p", 0);
144 pkt->ip_sum = htons (get_int_var_by_name (lexic, "ip_sum", 0));
145 /* source */
146 s = get_str_var_by_name (lexic, "ip_src");
147 if (s != NULL)
148 inet_aton (s, &pkt->ip_src);
149 /* else this host address? */
150
151 /* I know that this feature looks dangerous, but anybody can edit an IP
152 * packet with the string functions */
153 s = get_str_var_by_name (lexic, "ip_dst");
154 if (s != NULL)
155 inet_aton (s, &pkt->ip_dst);
156 else
157 pkt->ip_dst.s_addr = dst_addr->s6_addr32[3];
158
159 if (data != NULL)
160 {
161 bcopy (data, retc->x.str_val + sizeof (struct ip), data_len);
162 }
163
164 if (!pkt->ip_sum)
165 {
166 if (get_int_var_by_name (lexic, "ip_sum", -1) < 0)
167 pkt->ip_sum = np_in_cksum ((u_short *) pkt, sizeof (struct ip));
168 }
169
170 return retc;
171}
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(), nasl_perror(), np_in_cksum(), 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_packet()

tree_cell * forge_tcp_packet ( lex_ctxt * lexic)

Fills an IP datagram with TCP data. Note that the ip_p field is not updated. It returns the modified IP datagram. Its arguments are:

Parameters
[in]ipIP datagram to be filled.
[in]dataTCP data payload.
[in]th_ackAcknowledge number. NASL will convert it into network order if necessary. 0 by default.
[in]th_dportDestination port. NASL will convert it into network order if necessary. 0 by default.
[in]th_flagsTCP flags. 0 by default.
[in]th_offSize of the TCP header in 32 bits words. By default, 5.
[in]th_seqTCP sequence number. NASL will convert it into network order if necessary. Random by default.
[in]th_sportSource port. NASL will convert it into network order if necessary. 0 by default.
[in]th_sumTCP checksum. Right value is computed by default.
[in]th_urpUrgent pointer. 0 by default.
[in]th_winTCP window size. NASL will convert it into network order if necessary. 0 by default.
[in]th_x2Is a reserved field and should probably be left unchanged. 0 by default.
[in]update_ip_lenFlag (TRUE by default). If set, NASL will recompute the size field of the IP datagram.
Returns
Modified IP datagram.

Definition at line 555 of file nasl_packet_forgery.c.

556{
557 tree_cell *retc;
558 char *data;
559 int len;
560 struct ip *ip, *tcp_packet;
561 struct tcphdr *tcp;
562 int ipsz;
563
564 ip = (struct ip *) get_str_var_by_name (lexic, "ip");
565 if (ip == NULL)
566 {
567 nasl_perror (lexic,
568 "forge_tcp_packet: You must supply the 'ip' argument\n");
569 return NULL;
570 }
571
572 ipsz = get_var_size_by_name (lexic, "ip");
573 if (ipsz > ip->ip_hl * 4)
574 ipsz = ip->ip_hl * 4;
575
576 data = get_str_var_by_name (lexic, "data");
577 len = data == NULL ? 0 : get_var_size_by_name (lexic, "data");
578
580 tcp_packet = (struct ip *) g_malloc0 (ipsz + sizeof (struct tcphdr) + len);
581 retc->x.str_val = (char *) tcp_packet;
582
583 bcopy (ip, tcp_packet, ipsz);
584 /* recompute the ip checksum, because the ip length changed */
585 if (UNFIX (tcp_packet->ip_len) <= tcp_packet->ip_hl * 4)
586 {
587 if (get_int_var_by_name (lexic, "update_ip_len", 1))
588 {
589 tcp_packet->ip_len =
590 FIX (tcp_packet->ip_hl * 4 + sizeof (struct tcphdr) + len);
591 tcp_packet->ip_sum = 0;
592 tcp_packet->ip_sum =
593 np_in_cksum ((u_short *) tcp_packet, sizeof (struct ip));
594 }
595 }
596 tcp = (struct tcphdr *) ((char *) tcp_packet + tcp_packet->ip_hl * 4);
597
598 tcp->th_sport = ntohs (get_int_var_by_name (lexic, "th_sport", 0));
599 tcp->th_dport = ntohs (get_int_var_by_name (lexic, "th_dport", 0));
600 tcp->th_seq = htonl (get_int_var_by_name (lexic, "th_seq", rand ()));
601 tcp->th_ack = htonl (get_int_var_by_name (lexic, "th_ack", 0));
602 tcp->th_x2 = get_int_var_by_name (lexic, "th_x2", 0);
603 tcp->th_off = get_int_var_by_name (lexic, "th_off", 5);
604 tcp->th_flags = get_int_var_by_name (lexic, "th_flags", 0);
605 tcp->th_win = htons (get_int_var_by_name (lexic, "th_win", 0));
606 tcp->th_sum = get_int_var_by_name (lexic, "th_sum", 0);
607 tcp->th_urp = get_int_var_by_name (lexic, "th_urp", 0);
608
609 if (data != NULL)
610 bcopy (data, (char *) tcp + sizeof (struct tcphdr), len);
611
612 if (!tcp->th_sum)
613 {
614 struct pseudohdr pseudoheader;
615 char *tcpsumdata = g_malloc0 (sizeof (struct pseudohdr) + len + 1);
616 struct in_addr source, dest;
617
618 source.s_addr = ip->ip_src.s_addr;
619 dest.s_addr = ip->ip_dst.s_addr;
620
621 bzero (&pseudoheader, 12 + sizeof (struct tcphdr));
622 pseudoheader.saddr.s_addr = source.s_addr;
623 pseudoheader.daddr.s_addr = dest.s_addr;
624
625 pseudoheader.protocol = IPPROTO_TCP;
626 pseudoheader.length = htons (sizeof (struct tcphdr) + len);
627 bcopy ((char *) tcp, (char *) &pseudoheader.tcpheader,
628 sizeof (struct tcphdr));
629 /* fill tcpsumdata with data to checksum */
630 bcopy ((char *) &pseudoheader, tcpsumdata, sizeof (struct pseudohdr));
631 if (data != NULL)
632 bcopy ((char *) data, tcpsumdata + sizeof (struct pseudohdr), len);
633 tcp->th_sum = np_in_cksum ((unsigned short *) tcpsumdata,
634 12 + sizeof (struct tcphdr) + len);
635 g_free (tcpsumdata);
636 }
637
638 retc->size = ipsz + sizeof (struct tcphdr) + len;
639 return retc;
640}

References alloc_typed_cell(), CONST_DATA, pseudohdr::daddr, FIX, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), len, pseudohdr::length, nasl_perror(), np_in_cksum(), pseudohdr::protocol, pseudohdr::saddr, TC::size, TC::str_val, pseudohdr::tcpheader, UNFIX, and TC::x.

Here is the call graph for this function:

◆ forge_udp_packet()

tree_cell * forge_udp_packet ( lex_ctxt * lexic)

Fills an IP datagram with UDP data. Note that the ip_p field is not updated. It returns the modified IP datagram. Its arguments are:

Parameters
[in]ipIP datagram to be filled.
[in]dataPayload.
[in]uh_dportDestination port. NASL will convert it into network order if necessary. 0 by default.
[in]uh_sportSource port. NASL will convert it into network order if necessary. 0 by default.
[in]uh_sumUDP checksum. Although it is not compulsory, the right value is computed by default.
[in]uh_ulenData length. By default it is set to the length of the data argument plus the size of the UDP header.
[in]update_ip_lenFlag (TRUE by default). If set, NASL will recompute the size field of the IP datagram.
Returns
Modified IP datagram.

Definition at line 1451 of file nasl_packet_forgery.c.

1452{
1453 tree_cell *retc;
1454 struct ip *ip = (struct ip *) get_str_var_by_name (lexic, "ip");
1455
1456 if (ip != NULL)
1457 {
1458 char *data = get_str_var_by_name (lexic, "data");
1459 int data_len = get_var_size_by_name (lexic, "data");
1460 u_char *pkt;
1461 struct ip *udp_packet;
1462 struct udphdr *udp;
1463
1464 pkt = g_malloc0 (sizeof (struct udphdr) + ip->ip_hl * 4
1465 + sizeof (struct udphdr) + data_len);
1466
1467 udp_packet = (struct ip *) pkt;
1468 udp = (struct udphdr *) (pkt + ip->ip_hl * 4);
1469
1470 udp->uh_sport = htons (get_int_var_by_name (lexic, "uh_sport", 0));
1471 udp->uh_dport = htons (get_int_var_by_name (lexic, "uh_dport", 0));
1472 udp->uh_ulen = htons (get_int_var_by_name (
1473 lexic, "uh_ulen", data_len + sizeof (struct udphdr)));
1474
1475 /* printf("len : %d %s\n", len, data); */
1476 if (data_len != 0 && data != NULL)
1477 bcopy (data, (pkt + ip->ip_hl * 4 + sizeof (struct udphdr)), data_len);
1478
1479 udp->uh_sum = get_int_var_by_name (lexic, "uh_sum", 0);
1480 bcopy ((char *) ip, pkt, ip->ip_hl * 4);
1481 if (udp->uh_sum == 0)
1482 {
1484 struct in_addr source, dest;
1485 char *udpsumdata =
1486 g_malloc0 (sizeof (struct pseudo_udp_hdr) + data_len + 1);
1487
1488 source.s_addr = ip->ip_src.s_addr;
1489 dest.s_addr = ip->ip_dst.s_addr;
1490
1491 bzero (&pseudohdr, sizeof (struct pseudo_udp_hdr));
1492 pseudohdr.saddr.s_addr = source.s_addr;
1493 pseudohdr.daddr.s_addr = dest.s_addr;
1494
1495 pseudohdr.proto = IPPROTO_UDP;
1496 pseudohdr.len = htons (sizeof (struct udphdr) + data_len);
1497 bcopy ((char *) udp, (char *) &pseudohdr.udpheader,
1498 sizeof (struct udphdr));
1499 bcopy ((char *) &pseudohdr, udpsumdata, sizeof (pseudohdr));
1500 if (data != NULL)
1501 {
1502 bcopy ((char *) data, udpsumdata + sizeof (pseudohdr), data_len);
1503 }
1504 udp->uh_sum = np_in_cksum ((unsigned short *) udpsumdata,
1505 12 + sizeof (struct udphdr) + data_len);
1506 g_free (udpsumdata);
1507 }
1508
1509 if (UNFIX (udp_packet->ip_len) <= udp_packet->ip_hl * 4)
1510 {
1511 int v = get_int_var_by_name (lexic, "update_ip_len", 1);
1512 if (v != 0)
1513 {
1514 udp_packet->ip_len =
1515 FIX (ntohs (udp->uh_ulen) + (udp_packet->ip_hl * 4));
1516 udp_packet->ip_sum = 0;
1517 udp_packet->ip_sum =
1518 np_in_cksum ((u_short *) udp_packet, udp_packet->ip_hl * 4);
1519 }
1520 }
1521
1523 retc->x.str_val = (char *) pkt;
1524 retc->size = 8 + ip->ip_hl * 4 + data_len;
1525 return retc;
1526 }
1527 else
1528 nasl_perror (lexic,
1529 "forge_udp_packet: Invalid value for the argument 'ip'\n");
1530
1531 return NULL;
1532}
struct in_addr saddr
struct in_addr daddr

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

Here is the call graph for this function:

◆ get_icmp_element()

tree_cell * get_icmp_element ( lex_ctxt * lexic)

Get an ICMP element from a IP datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]icmpFull IP datagram (IP + ICMP).
[in]elementName of the TCP field (see forge_tcp_packet()).
Returns
Data block or an integer, according to the type of the element.

Definition at line 1854 of file nasl_packet_forgery.c.

1855{
1856 struct icmp *icmp;
1857 char *p;
1858
1859 if ((p = get_str_var_by_name (lexic, "icmp")) != NULL)
1860 {
1861 char *elem = get_str_var_by_name (lexic, "element");
1862 int value;
1863 struct ip *ip = (struct ip *) p;
1864 tree_cell *retc;
1865
1866 icmp = (struct icmp *) (p + ip->ip_hl * 4);
1867
1868 if (elem == NULL)
1869 {
1870 nasl_perror (lexic,
1871 "get_icmp_element: missing 'element' parameter\n");
1872 return NULL;
1873 }
1874
1875 if (!strcmp (elem, "icmp_id"))
1876 value = ntohs (icmp->icmp_id);
1877 else if (!strcmp (elem, "icmp_code"))
1878 value = icmp->icmp_code;
1879 else if (!strcmp (elem, "icmp_type"))
1880 value = icmp->icmp_type;
1881 else if (!strcmp (elem, "icmp_seq"))
1882 value = ntohs (icmp->icmp_seq);
1883 else if (!strcmp (elem, "icmp_cksum"))
1884 value = ntohs (icmp->icmp_cksum);
1885 else if (!strcmp (elem, "data"))
1886 {
1888 retc->size =
1889 get_var_size_by_name (lexic, "icmp") - (ip->ip_hl * 4) - 8;
1890 if (retc->size > 0)
1891 {
1892 retc->x.str_val = g_malloc0 (retc->size + 1);
1893 memcpy (retc->x.str_val, &(p[ip->ip_hl * 4 + 8]), retc->size + 1);
1894 }
1895 else
1896 {
1897 retc->x.str_val = NULL;
1898 retc->size = 0;
1899 }
1900 return retc;
1901 }
1902 else
1903 {
1904 nasl_perror (
1905 lexic,
1906 "get_icmp_element: Element '%s' is not a valid element to get.\n",
1907 elem);
1908 return NULL;
1909 }
1910
1911 retc = alloc_typed_cell (CONST_INT);
1912 retc->x.i_val = value;
1913 return retc;
1914 }
1915 else
1916 nasl_perror (lexic, "get_icmp_element: missing 'icmp' parameter\n");
1917
1918 return NULL;
1919}
@ 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_element()

tree_cell * get_ip_element ( lex_ctxt * lexic)

Extracts a field from an IP datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]elementName of the field, e.g. "ip_len" or "ip_src".
[in]ipIP datagram or fragment.
Returns
integer or a string, depending on the type of the element.

Definition at line 183 of file nasl_packet_forgery.c.

184{
185 tree_cell *retc;
186 struct ip *ip = (struct ip *) get_str_var_by_name (lexic, "ip");
187 char *element = get_str_var_by_name (lexic, "element");
188 char ret_ascii[32];
189 int ret_int = 0;
190 int flag = 0;
191
192 if (ip == NULL)
193 {
194 nasl_perror (lexic, "get_ip_element: no valid 'ip' argument\n");
195 return NULL;
196 }
197
198 if (element == NULL)
199 {
200 nasl_perror (lexic, "get_ip_element: no valid 'element' argument\n");
201 return NULL;
202 }
203
204 if (!strcmp (element, "ip_v"))
205 {
206 ret_int = ip->ip_v;
207 flag++;
208 }
209 else if (!strcmp (element, "ip_id"))
210 {
211 ret_int = UNFIX (ip->ip_id);
212 flag++;
213 }
214 else if (!strcmp (element, "ip_hl"))
215 {
216 ret_int = ip->ip_hl;
217 flag++;
218 }
219 else if (!strcmp (element, "ip_tos"))
220 {
221 ret_int = ip->ip_tos;
222 flag++;
223 }
224 else if (!strcmp (element, "ip_len"))
225 {
226 ret_int = UNFIX (ip->ip_len);
227 flag++;
228 }
229 else if (!strcmp (element, "ip_off"))
230 {
231 ret_int = UNFIX (ip->ip_off);
232 flag++;
233 }
234 else if (!strcmp (element, "ip_ttl"))
235 {
236 ret_int = ip->ip_ttl;
237 flag++;
238 }
239 else if (!strcmp (element, "ip_p"))
240 {
241 ret_int = ip->ip_p;
242 flag++;
243 }
244 else if (!strcmp (element, "ip_sum"))
245 {
246 ret_int = UNFIX (ip->ip_sum);
247 flag++;
248 }
249
250 if (flag != 0)
251 {
253 retc->x.i_val = ret_int;
254 return retc;
255 }
256
257 if (!strcmp (element, "ip_src"))
258 {
259 snprintf (ret_ascii, sizeof (ret_ascii), "%s", inet_ntoa (ip->ip_src));
260 flag++;
261 }
262 else if (!strcmp (element, "ip_dst"))
263 {
264 snprintf (ret_ascii, sizeof (ret_ascii), "%s", inet_ntoa (ip->ip_dst));
265 flag++;
266 }
267
268 if (flag == 0)
269 {
270 nasl_perror (lexic, "%s: unknown element '%s'\n", __func__, element);
271 return NULL;
272 }
273
275 retc->size = strlen (ret_ascii);
276 retc->x.str_val = g_strdup (ret_ascii);
277
278 return retc;
279}

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_element()

tree_cell * get_tcp_element ( lex_ctxt * lexic)

Extracts TCP field from an IP datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]elementName of the the TCP field. See forge_tcp_packet().
[in]tcpThe full IP datagram (IP + TCP).
Returns
Data block or an integer, according to the type of the element.

Definition at line 652 of file nasl_packet_forgery.c.

653{
654 u_char *packet = (u_char *) get_str_var_by_name (lexic, "tcp");
655 struct ip *ip;
656 int ipsz;
657 struct tcphdr *tcp;
658 char *element;
659 int ret;
660 tree_cell *retc;
661
662 ipsz = get_var_size_by_name (lexic, "tcp");
663
664 if (packet == NULL)
665 {
666 nasl_perror (lexic, "get_tcp_element: No valid 'tcp' argument\n");
667 return NULL;
668 }
669
670 ip = (struct ip *) packet;
671
672 if (ip->ip_hl * 4 > ipsz)
673 return NULL; /* Invalid packet */
674
675 if (UNFIX (ip->ip_len) > ipsz)
676 return NULL; /* Invalid packet */
677
678 tcp = (struct tcphdr *) (packet + ip->ip_hl * 4);
679
680 element = get_str_var_by_name (lexic, "element");
681 if (!element)
682 {
683 nasl_perror (lexic, "get_tcp_element: No valid 'element' argument\n");
684 return NULL;
685 }
686
687 if (!strcmp (element, "th_sport"))
688 ret = ntohs (tcp->th_sport);
689 else if (!strcmp (element, "th_dsport"))
690 ret = ntohs (tcp->th_dport);
691 else if (!strcmp (element, "th_seq"))
692 ret = ntohl (tcp->th_seq);
693 else if (!strcmp (element, "th_ack"))
694 ret = ntohl (tcp->th_ack);
695 else if (!strcmp (element, "th_x2"))
696 ret = tcp->th_x2;
697 else if (!strcmp (element, "th_off"))
698 ret = tcp->th_off;
699 else if (!strcmp (element, "th_flags"))
700 ret = tcp->th_flags;
701 else if (!strcmp (element, "th_win"))
702 ret = ntohs (tcp->th_win);
703 else if (!strcmp (element, "th_sum"))
704 ret = tcp->th_sum;
705 else if (!strcmp (element, "th_urp"))
706 ret = tcp->th_urp;
707 else if (!strcmp (element, "data"))
708 {
710 retc->size = UNFIX (ip->ip_len) - (tcp->th_off + ip->ip_hl) * 4;
711 retc->x.str_val = g_malloc0 (retc->size);
712 bcopy ((char *) tcp + tcp->th_off * 4, retc->x.str_val, retc->size);
713 return retc;
714 }
715 else
716 {
717 nasl_perror (lexic, "get_tcp_element: Unknown tcp field %s\n", element);
718 return NULL;
719 }
720
722 retc->x.i_val = ret;
723 return retc;
724}

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, UNFIX, and TC::x.

Here is the call graph for this function:

◆ get_tcp_option()

tree_cell * get_tcp_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 802 of file nasl_packet_forgery.c.

803{
804 u_char *packet = (u_char *) get_str_var_by_name (lexic, "tcp");
805 struct ip *ip;
806 int ipsz;
807 struct tcphdr *tcp;
808 char *options;
809 int opt;
810 tree_cell *retc;
811 nasl_array *arr;
813
814 struct tcp_options *tcp_all_options = NULL;
815
816 if (packet == NULL)
817 {
818 nasl_perror (lexic, "%s: No valid 'tcp' argument passed.\n", __func__);
819 return NULL;
820 }
821
822 opt = get_int_var_by_name (lexic, "option", -1);
823 if (opt < 0)
824 {
825 nasl_perror (lexic,
826 "%s: No options\n."
827 "Usage: %s(tcp:<tcp>, option:<TCPOPT>)",
828 __func__, __func__);
829 return NULL;
830 }
831
832 ip = (struct ip *) packet;
833
834 ipsz = get_var_size_by_name (lexic, "tcp");
835 if (ip->ip_hl * 4 > ipsz)
836 return NULL; /* Invalid packet */
837
838 if (UNFIX (ip->ip_len) > ipsz)
839 return NULL; /* Invalid packet */
840
841 tcp = (struct tcphdr *) (packet + ip->ip_hl * 4);
842
843 if (tcp->th_off <= 5)
844 return NULL;
845
846 // Get options from the segment
847 options = (char *) g_malloc0 (sizeof (uint8_t) * 4 * (tcp->th_off - 5));
848 memcpy (options, (char *) tcp + 20, (tcp->th_off - 5) * 4);
849
850 tcp_all_options = g_malloc0 (sizeof (struct tcp_options));
851 get_tcp_options (options, tcp_all_options);
852 if (tcp_all_options == NULL)
853 {
854 nasl_perror (lexic, "%s: No TCP options found in passed TCP packet.\n",
855 __func__);
856
857 g_free (options);
858 return NULL;
859 }
860
861 opt = get_int_var_by_name (lexic, "option", -1);
862 retc = NULL;
863 switch (opt)
864 {
865 case TCPOPT_MAXSEG:
867 retc->x.i_val = ntohs ((uint16_t) tcp_all_options->mss.mss);
868 break;
869 case TCPOPT_WINDOW:
871 retc->x.i_val = tcp_all_options->wscale.wscale;
872 break;
873 case TCPOPT_SACK_PERMITTED:
875 retc->x.i_val = tcp_all_options->sack_perm.kind ? 1 : 0;
876 break;
877 case TCPOPT_TIMESTAMP:
879 retc->x.ref_val = arr = g_malloc0 (sizeof (nasl_array));
880
881 memset (&v, 0, sizeof (v));
882 v.var_type = VAR2_INT;
883 v.v.v_int = ntohl ((uint32_t) tcp_all_options->tstamp.tstamp);
884 add_var_to_array (arr, "timestamp", &v);
885
886 memset (&v, 0, sizeof (v));
887 v.var_type = VAR2_INT;
888 v.v.v_int = ntohl ((uint32_t) tcp_all_options->tstamp.e_tstamp);
889 add_var_to_array (arr, "echo_timestamp", &v);
890 break;
891 default:
892 nasl_perror (lexic, "%s: Invalid TCP option passed.\n", __func__);
893 break;
894 }
895
896 g_free (tcp_all_options);
897 g_free (options);
898 return retc;
899}
@ 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_element()

tree_cell * get_udp_element ( lex_ctxt * lexic)

Get an UDP element from a IP datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]udpThe full IP datagram (IP + UDP).
[in]elementName of the UDP field (see forge_udp_packet()).
Returns
Data block or an integer, according to the type of the element.

Definition at line 1544 of file nasl_packet_forgery.c.

1545{
1546 tree_cell *retc;
1547 char *udp;
1548 char *element;
1549 struct ip *ip;
1550 unsigned int ipsz;
1551 struct udphdr *udphdr;
1552 int ret;
1553
1554 udp = get_str_var_by_name (lexic, "udp");
1555 ipsz = get_var_size_by_name (lexic, "udp");
1556
1557 element = get_str_var_by_name (lexic, "element");
1558 if (udp == NULL || element == NULL)
1559 {
1560 nasl_perror (lexic, "get_udp_element: usage :\nelement = "
1561 "get_udp_element(udp:<udp>,element:<element>\n");
1562 return NULL;
1563 }
1564 ip = (struct ip *) udp;
1565
1566 if (ip->ip_hl * 4 + sizeof (struct udphdr) > ipsz)
1567 return NULL;
1568
1569 udphdr = (struct udphdr *) (udp + ip->ip_hl * 4);
1570 if (!strcmp (element, "uh_sport"))
1571 ret = ntohs (udphdr->uh_sport);
1572 else if (!strcmp (element, "uh_dport"))
1573 ret = ntohs (udphdr->uh_dport);
1574 else if (!strcmp (element, "uh_ulen"))
1575 ret = ntohs (udphdr->uh_ulen);
1576 else if (!strcmp (element, "uh_sum"))
1577 ret = ntohs (udphdr->uh_sum);
1578 else if (!strcmp (element, "data"))
1579 {
1580 int sz;
1582 sz = ntohs (udphdr->uh_ulen) - sizeof (struct udphdr);
1583
1584 if (ntohs (udphdr->uh_ulen) - ip->ip_hl * 4 - sizeof (struct udphdr)
1585 > ipsz)
1586 sz = ipsz - ip->ip_hl * 4 - sizeof (struct udphdr);
1587
1588 retc->x.str_val = g_malloc0 (sz);
1589 retc->size = sz;
1590 bcopy (udp + ip->ip_hl * 4 + sizeof (struct udphdr), retc->x.str_val, sz);
1591 return retc;
1592 }
1593 else
1594 {
1595 nasl_perror (lexic, "%s: '%s' is not a value of a udp packet\n", __func__,
1596 element);
1597 return NULL;
1598 }
1599
1600 retc = alloc_typed_cell (CONST_INT);
1601 retc->x.i_val = ret;
1602 return retc;
1603}

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_options()

tree_cell * insert_ip_options ( lex_ctxt * lexic)

Add option datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]ipIP datagram to add the option to.
[in]codeNumber of the option.
[in]lengthLength of the option data.
[in]valueOption data.
Returns
The modified IP datagram.

Definition at line 357 of file nasl_packet_forgery.c.

358{
359 struct ip *ip = (struct ip *) get_str_var_by_name (lexic, "ip");
360 int code = get_int_var_by_name (lexic, "code", 0);
361 int len = get_int_var_by_name (lexic, "length", 0);
362 char *value = get_str_var_by_name (lexic, "value");
363 int value_size = get_var_size_by_name (lexic, "value");
364 tree_cell *retc;
365 struct ip *new_packet;
366 char *p;
367 int size = get_var_size_by_name (lexic, "ip");
368 u_char uc_code, uc_len;
369 int pad_len;
370 char zero = '0';
371 int i;
372 int hl;
373
374 if (ip == NULL)
375 {
376 nasl_perror (lexic, "Usage : insert_ip_options(ip:<ip>, code:<code>, "
377 "length:<len>, value:<value>\n");
378 return NULL;
379 }
380
381 pad_len = 4 - ((sizeof (uc_code) + sizeof (uc_len) + value_size) % 4);
382 if (pad_len == 4)
383 pad_len = 0;
384
385 hl = ip->ip_hl * 4 < UNFIX (ip->ip_len) ? ip->ip_hl * 4 : UNFIX (ip->ip_len);
386 new_packet = g_malloc0 (size + 4 + value_size + pad_len);
387 bcopy (ip, new_packet, hl);
388
389 uc_code = (u_char) code;
390 uc_len = (u_char) len;
391
392 p = (char *) new_packet;
393 bcopy (&uc_code, p + hl, sizeof (uc_code));
394 bcopy (&uc_len, p + hl + sizeof (uc_code), sizeof (uc_len));
395 bcopy (value, p + hl + sizeof (uc_code) + sizeof (uc_len), value_size);
396
397 zero = 0;
398 for (i = 0; i < pad_len; i++)
399 {
400 bcopy (&zero,
401 p + hl + sizeof (uc_code) + sizeof (uc_len) + value_size + i, 1);
402 }
403
404 p = (char *) ip;
405 bcopy (p + hl,
406 new_packet
407 + (sizeof (uc_code) + sizeof (uc_len) + value_size + pad_len) + hl,
408 size - hl);
409
410 new_packet->ip_hl =
411 (hl + (sizeof (uc_code) + sizeof (uc_len) + value_size + pad_len)) / 4;
412 new_packet->ip_len =
413 FIX (size + sizeof (uc_code) + sizeof (uc_len) + value_size + pad_len);
414 new_packet->ip_sum = 0;
415 new_packet->ip_sum = np_in_cksum (
416 (u_short *) new_packet, new_packet->ip_hl * 4 > UNFIX (new_packet->ip_len)
417 ? UNFIX (new_packet->ip_len)
418 : new_packet->ip_hl * 4);
419
421 retc->size = size + value_size + sizeof (uc_code) + sizeof (uc_len) + pad_len;
422 retc->x.str_val = (char *) new_packet;
423
424 return retc;
425}
#define code
u_char zero

References alloc_typed_cell(), code, 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, TC::x, and zero.

Here is the call graph for this function:

◆ insert_tcp_options()

tree_cell * insert_tcp_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 1042 of file nasl_packet_forgery.c.

1043{
1044 char *pkt = get_str_var_by_name (lexic, "tcp");
1045 struct ip *ip = (struct ip *) pkt;
1046 int pktsz = get_var_size_by_name (lexic, "tcp");
1047 struct tcphdr *tcp;
1048 tree_cell *retc;
1049 char *data = get_str_var_by_name (lexic, "data");
1050 int data_len = get_var_size_by_name (lexic, "data");
1051 char *npkt;
1052 int tcp_opt, tcp_opt_val, tcp_opt_val2;
1053 int current_opt_len, total_opt_len, opt_size_allocated;
1054 char *opts, *ptr_opts_pos;
1055 uint8_t eol, nop;
1056 int i;
1057
1058 struct tcp_opt_mss *opt_mss;
1059 struct tcp_opt_wscale *opt_wscale;
1060 struct tcp_opt_sack_perm *opt_sack_perm;
1061 struct tcp_opt_tstamp *opt_tstamp;
1062
1063 if (!ip)
1064 {
1065 nasl_perror (lexic, "%s: Invalid value for the argument 'tcp'\n",
1066 __func__);
1067 return NULL;
1068 }
1069
1070 opts = g_malloc0 (sizeof (char) * 4);
1071 ptr_opts_pos = opts;
1072 opt_size_allocated = 4; // 4 bytes
1073 total_opt_len = 0;
1074 for (i = 0;; i++)
1075 {
1076 tcp_opt = get_int_var_by_num (lexic, i, -1);
1077 current_opt_len = total_opt_len;
1078
1079 if (tcp_opt == -1)
1080 break;
1081
1082 switch (tcp_opt)
1083 {
1084 case TCPOPT_MAXSEG:
1085 tcp_opt_val = get_int_var_by_num (lexic, i + 1, -1);
1086 i++;
1087 if (tcp_opt_val < (int) TCP_MSS_DEFAULT || tcp_opt_val > 65535)
1088 {
1089 nasl_perror (lexic, "%s: Invalid value for TCP option MSS\n",
1090 __func__);
1091 break;
1092 }
1093 opt_mss = g_malloc0 (sizeof (struct tcp_opt_mss));
1094 total_opt_len += TCPOLEN_MAXSEG;
1095 opt_mss->kind = TCPOPT_MAXSEG;
1096 opt_mss->len = TCPOLEN_MAXSEG;
1097 opt_mss->mss = FIX (tcp_opt_val);
1098
1099 // Need reallocated memory because options requires it.
1100 if (total_opt_len > opt_size_allocated)
1101 {
1102 opt_size_allocated = ((total_opt_len / 4) + 1) * 4;
1103 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1104 ptr_opts_pos = opts + current_opt_len;
1105 }
1106
1107 memcpy (ptr_opts_pos, (u_char *) opt_mss,
1108 sizeof (struct tcp_opt_mss));
1109 ptr_opts_pos = ptr_opts_pos + sizeof (struct tcp_opt_mss);
1110 g_free (opt_mss);
1111 break;
1112 case TCPOPT_WINDOW:
1113 tcp_opt_val = get_int_var_by_num (lexic, i + 1, -1);
1114 i++;
1115 if (tcp_opt_val < 0 || tcp_opt_val > 14)
1116 {
1117 nasl_perror (lexic, "%s: Invalid value for TCP option WScale\n",
1118 __func__);
1119 break;
1120 }
1121 opt_wscale = g_malloc0 (sizeof (struct tcp_opt_wscale));
1122 total_opt_len += TCPOLEN_WINDOW;
1123 opt_wscale->kind = TCPOPT_WINDOW;
1124 opt_wscale->len = TCPOLEN_WINDOW;
1125 opt_wscale->wscale = tcp_opt_val;
1126
1127 // Need reallocated memory because options requires it.
1128 if (total_opt_len > opt_size_allocated)
1129 {
1130 opt_size_allocated = ((total_opt_len / 4) + 1) * 4;
1131 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1132 ptr_opts_pos = opts + current_opt_len;
1133 }
1134
1135 memcpy (ptr_opts_pos, (u_char *) opt_wscale,
1136 sizeof (struct tcp_opt_wscale));
1137 ptr_opts_pos = ptr_opts_pos + sizeof (struct tcp_opt_wscale);
1138 g_free (opt_wscale);
1139 break;
1140 case TCPOPT_SACK_PERMITTED:
1141 opt_sack_perm = g_malloc0 (sizeof (struct tcp_opt_sack_perm));
1142 total_opt_len += TCPOLEN_SACK_PERMITTED;
1143 opt_sack_perm->kind = TCPOPT_SACK_PERMITTED;
1144 opt_sack_perm->len = TCPOLEN_SACK_PERMITTED;
1145
1146 // Need reallocated memory because options requires it.
1147 if (total_opt_len > opt_size_allocated)
1148 {
1149 opt_size_allocated = ((total_opt_len / 4) + 1) * 4;
1150 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1151 ptr_opts_pos = opts + current_opt_len;
1152 }
1153
1154 memcpy (ptr_opts_pos, (u_char *) opt_sack_perm,
1155 sizeof (struct tcp_opt_sack_perm));
1156 ptr_opts_pos = ptr_opts_pos + sizeof (struct tcp_opt_sack_perm);
1157 g_free (opt_sack_perm);
1158 break;
1159 case TCPOPT_TIMESTAMP:
1160 tcp_opt_val = get_int_var_by_num (lexic, i + 1, -1);
1161 tcp_opt_val2 = get_int_var_by_num (lexic, i + 2, -1);
1162 i = i + 2;
1163 if (tcp_opt_val < 0)
1164 nasl_perror (lexic, "%s: Invalid value for TCP option Timestamp\n",
1165 __func__);
1166 opt_tstamp = g_malloc0 (sizeof (struct tcp_opt_tstamp));
1167 total_opt_len += TCPOLEN_TIMESTAMP;
1168 opt_tstamp->kind = TCPOPT_TIMESTAMP;
1169 opt_tstamp->len = TCPOLEN_TIMESTAMP;
1170 opt_tstamp->tstamp = htonl (tcp_opt_val);
1171 opt_tstamp->e_tstamp = htonl (tcp_opt_val2);
1172
1173 // Need reallocated memory because options requires it.
1174 if (total_opt_len > opt_size_allocated)
1175 {
1176 opt_size_allocated = ((total_opt_len / 4) + 1) * 4;
1177 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1178 ptr_opts_pos = opts + current_opt_len;
1179 }
1180
1181 memcpy (ptr_opts_pos, (u_char *) opt_tstamp,
1182 sizeof (struct tcp_opt_tstamp));
1183 ptr_opts_pos = ptr_opts_pos + sizeof (struct tcp_opt_tstamp);
1184 g_free (opt_tstamp);
1185 break;
1186 case TCPOPT_NOP:
1187 case TCPOPT_EOL:
1188 case TCPOPT_SACK: /* Experimental, not supported */
1189 default:
1190 nasl_perror (lexic, "%s: TCP option %d not supported\n", __func__,
1191 tcp_opt);
1192 break;
1193 }
1194 }
1195
1196 // Add NOP padding and End Of Option list kinds.
1197 current_opt_len = total_opt_len;
1198 eol = TCPOPT_EOL;
1199 nop = TCPOPT_NOP;
1200 if (total_opt_len % 4 == 0)
1201 {
1202 opt_size_allocated = opt_size_allocated + 4;
1203 opts = g_realloc (opts, sizeof (char) * opt_size_allocated);
1204 ptr_opts_pos = opts + total_opt_len;
1205 }
1206 if (current_opt_len < opt_size_allocated - 1)
1207 {
1208 // Add NOPs
1209 for (i = current_opt_len; i < opt_size_allocated - 1; i++)
1210 {
1211 memcpy (ptr_opts_pos, &nop, 1);
1212 total_opt_len++;
1213 ptr_opts_pos++;
1214 }
1215 }
1216 // Add EOL
1217 memcpy (ptr_opts_pos, &eol, 1);
1218
1219 if (ip->ip_hl * 4 > pktsz)
1220 // ip->ip_hl is bogus, we work around that
1221 tcp = (struct tcphdr *) (pkt + 20);
1222 else
1223 tcp = (struct tcphdr *) (pkt + ip->ip_hl * 4);
1224
1225 if (pktsz < UNFIX (ip->ip_len))
1226 {
1227 g_free (opts);
1228 return NULL;
1229 }
1230
1231 if (data_len == 0)
1232 {
1233 data_len = UNFIX (ip->ip_len) - (ip->ip_hl * 4) - (tcp->th_off * 4);
1234 data = (char *) ((char *) tcp + tcp->th_off * 4);
1235 }
1236
1237 // Alloc enough memory to hold the options
1238 npkt =
1239 g_malloc0 (ip->ip_hl * 4 + tcp->th_off * 4 + opt_size_allocated + data_len);
1240 memcpy (npkt, pkt, UNFIX (ip->ip_len));
1241 ip = (struct ip *) (npkt);
1242 tcp = (struct tcphdr *) (npkt + ip->ip_hl * 4);
1243
1244 // copy options
1245 memcpy ((char *) tcp + tcp->th_off * 4, opts, opt_size_allocated);
1246
1247 tcp->th_off = tcp->th_off + (opt_size_allocated / 4);
1248 memcpy ((char *) tcp + tcp->th_off * 4, data, data_len);
1249
1250 // Update ip_len and calculate ip checksum
1251 ip->ip_len = FIX (ip->ip_hl * 4 + tcp->th_off * 4 + data_len);
1252 ip->ip_sum = 0;
1253 ip->ip_sum = np_in_cksum ((u_short *) npkt, ip->ip_hl * 4);
1254
1255 // Calculate tcp header with options checksum
1256 struct pseudohdr pseudoheader;
1257 char *tcpsumdata =
1258 g_malloc0 (sizeof (struct pseudohdr) + opt_size_allocated + data_len + 1);
1259 struct in_addr source, dest;
1260
1261 source.s_addr = ip->ip_src.s_addr;
1262 dest.s_addr = ip->ip_dst.s_addr;
1263
1264 memset (&pseudoheader, 0, sizeof (struct pseudohdr));
1265 pseudoheader.saddr.s_addr = source.s_addr;
1266 pseudoheader.daddr.s_addr = dest.s_addr;
1267
1268 pseudoheader.protocol = IPPROTO_TCP;
1269 // TCP length is tcpheader + options + data
1270 pseudoheader.length =
1271 htons (sizeof (struct tcphdr) + opt_size_allocated + data_len);
1272
1273 // Set th_sum to Zero, necessary for the new checksum calculation
1274 tcp->th_sum = 0;
1275
1276 memcpy ((char *) &pseudoheader.tcpheader, (char *) tcp,
1277 sizeof (struct tcphdr));
1278
1279 /* fill tcpsumdata with data to checksum */
1280 memcpy (tcpsumdata, (char *) &pseudoheader, sizeof (struct pseudohdr));
1281 memcpy (tcpsumdata + sizeof (struct pseudohdr), (char *) opts,
1282 opt_size_allocated);
1283 memcpy (tcpsumdata + sizeof (struct pseudohdr) + opt_size_allocated,
1284 (char *) data, data_len);
1285 tcp->th_sum =
1286 np_in_cksum ((unsigned short *) tcpsumdata,
1287 sizeof (struct pseudohdr) + opt_size_allocated + data_len);
1288 g_free (opts);
1289 g_free (tcpsumdata);
1290
1292 retc->size = (ip->ip_hl * 4) + (tcp->th_off * 4) + data_len;
1293 retc->x.str_val = npkt;
1294 return retc;
1295}
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition nasl_var.c:1094

References alloc_typed_cell(), CONST_DATA, pseudohdr::daddr, 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, pseudohdr::length, tcp_opt_mss::mss, nasl_perror(), np_in_cksum(), pseudohdr::protocol, pseudohdr::saddr, TC::size, TC::str_val, pseudohdr::tcpheader, tcp_opt_tstamp::tstamp, UNFIX, tcp_opt_wscale::wscale, and TC::x.

Here is the call graph for this function:

◆ nasl_pcap_next()

tree_cell * nasl_pcap_next ( lex_ctxt * lexic)

Listen to one packet and return it.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]interfaceNetwork interface name. By default, NASL will try to find the best one.
[in]pcap_filterBPF filter. By default, it listens to everything.
[in]timeout5 seconds by default.
Returns
Packet which was captured.

Definition at line 2338 of file nasl_packet_forgery.c.

2339{
2340 char *interface = get_str_var_by_name (lexic, "interface");
2341 int bpf = -1;
2342 static char errbuf[PCAP_ERRBUF_SIZE];
2343 int is_ip = 0;
2344 struct ip *ret = NULL;
2345 struct ip6_hdr *ret6 = NULL;
2346 char *filter = get_str_var_by_name (lexic, "pcap_filter");
2347 pcap_if_t *alldevsp = NULL; /* list of capture devices */
2348 int timeout = get_int_var_by_name (lexic, "timeout", 5);
2349 tree_cell *retc;
2350 int sz;
2351 struct in6_addr *dst = plug_get_host_ip (lexic->script_infos);
2352 struct in_addr inaddr;
2353
2354 if (dst == NULL)
2355 {
2356 return NULL;
2357 }
2358 int v4_addr = IN6_IS_ADDR_V4MAPPED (dst);
2359 if (interface == NULL)
2360 {
2361 if (v4_addr)
2362 {
2363 struct in_addr src;
2364 bzero (&src, sizeof (src));
2365 inaddr.s_addr = dst->s6_addr32[3];
2366 interface = routethrough (&inaddr, &src);
2367 }
2368 else
2369 {
2370 struct in6_addr src;
2371 bzero (&src, sizeof (src));
2372 interface = v6_routethrough (dst, &src);
2373 }
2374 if (interface == NULL)
2375 {
2376 if (pcap_findalldevs (&alldevsp, errbuf) < 0)
2377 g_message ("Error for pcap_findalldevs(): %s", errbuf);
2378 if (alldevsp != NULL)
2379 interface = alldevsp->name;
2380 }
2381 }
2382
2383 if (interface != NULL)
2384 {
2385 bpf = bpf_open_live (interface, filter);
2386 }
2387
2388 if (bpf < 0)
2389 {
2390 nasl_perror (lexic, "pcap_next: Could not get a bpf\n");
2391 return NULL;
2392 }
2393 else
2394 {
2395 int len;
2396 int dl_len = get_datalink_size (bpf_datalink (bpf));
2397 char *packet;
2398 struct timeval then, now;
2399
2400 gettimeofday (&then, NULL);
2401 for (;;)
2402 {
2403 packet = (char *) bpf_next (bpf, &len);
2404
2405 if (packet != NULL)
2406 break;
2407
2408 if (timeout != 0)
2409 {
2410 gettimeofday (&now, NULL);
2411 if (now.tv_sec - then.tv_sec >= timeout)
2412 {
2413 break;
2414 }
2415 }
2416 }
2417
2418 if (packet)
2419 {
2420 if (v4_addr)
2421 {
2422 struct ip *ip;
2423 ip = (struct ip *) (packet + dl_len);
2424 sz = UNFIX (ip->ip_len);
2425 ret = g_malloc0 (sz);
2426
2427 is_ip = (ip->ip_v == 4);
2428
2429 if (is_ip)
2430 {
2431 bcopy (ip, ret, sz);
2432 }
2433 else
2434 {
2435 sz = len - dl_len;
2436 bcopy (ip, ret, sz);
2437 }
2438 }
2439 else
2440 {
2441 struct ip6_hdr *ip;
2442 ip = (struct ip6_hdr *) (packet + dl_len);
2443 sz = UNFIX (ip->ip6_plen);
2444 ret6 = g_malloc0 (sz);
2445
2446 is_ip = ((ip->ip6_flow & 0x3ffff) == 96);
2447 if (is_ip)
2448 {
2449 bcopy (ip, ret6, sz);
2450 }
2451 else
2452 {
2453 sz = len - dl_len;
2454 bcopy (ip, ret6, sz);
2455 }
2456 }
2457 }
2458 else
2459 {
2460 bpf_close (bpf);
2461 return NULL;
2462 }
2463 }
2464 bpf_close (bpf);
2466 if (v4_addr)
2467 retc->x.str_val = (char *) ret;
2468 else
2469 retc->x.str_val = (char *) ret6;
2470 retc->size = sz;
2471
2472 if (alldevsp != NULL)
2473 pcap_freealldevs (alldevsp);
2474
2475 return retc;
2476}
int bpf_open_live(char *iface, char *filter)
Definition bpf_share.c:39
int bpf_datalink(int bpf)
Definition bpf_share.c:158
void bpf_close(int bpf)
Definition bpf_share.c:164
u_char * bpf_next(int bpf, int *caplen)
Definition bpf_share.c:150
static struct timeval timeval(unsigned long val)
const char * name
Definition nasl_init.c:439
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...
Definition pcap.c:1070
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
int get_datalink_size(int datalink)
Definition pcap.c:298

References alloc_typed_cell(), bpf_close(), bpf_datalink(), bpf_next(), bpf_open_live(), CONST_DATA, get_datalink_size(), get_int_var_by_name(), get_str_var_by_name(), len, name, nasl_perror(), plug_get_host_ip(), routethrough(), struct_lex_ctxt::script_infos, TC::size, TC::str_val, timeval(), UNFIX, v6_routethrough(), and TC::x.

Here is the call graph for this function:

◆ nasl_send_capture()

tree_cell * nasl_send_capture ( lex_ctxt * lexic)

Send a capture.

Parameters
[in]interfacestring
[in]pcapfilter string
[in]timeoutinteger
Returns
Packet which was captured.

Definition at line 2488 of file nasl_packet_forgery.c.

2489{
2490 char *interface = get_str_var_by_name (lexic, "interface");
2491 int bpf = -1;
2492 static char errbuf[PCAP_ERRBUF_SIZE];
2493 int is_ip = 0;
2494 struct ip *ret = NULL;
2495 struct ip6_hdr *ret6 = NULL;
2496 char *filter = get_str_var_by_name (lexic, "pcap_filter");
2497 pcap_if_t *alldevsp = NULL; /* list of capture devices */
2498 int timeout = get_int_var_by_name (lexic, "timeout", 5);
2499 tree_cell *retc;
2500 int sz;
2501 struct in6_addr *dst = plug_get_host_ip (lexic->script_infos);
2502 struct in_addr inaddr;
2503
2504 if (dst == NULL)
2505 return NULL;
2506
2507 int v4_addr = IN6_IS_ADDR_V4MAPPED (dst);
2508 if (interface == NULL)
2509 {
2510 if (v4_addr)
2511 {
2512 struct in_addr src;
2513 bzero (&src, sizeof (src));
2514 inaddr.s_addr = dst->s6_addr32[3];
2515 interface = routethrough (&inaddr, &src);
2516 }
2517 else
2518 {
2519 struct in6_addr src;
2520 bzero (&src, sizeof (src));
2521 interface = v6_routethrough (dst, &src);
2522 }
2523 if (interface == NULL)
2524 {
2525 if (pcap_findalldevs (&alldevsp, errbuf) < 0)
2526 g_message ("Error for pcap_findalldevs(): %s", errbuf);
2527 if (alldevsp != NULL)
2528 interface = alldevsp->name;
2529 }
2530 }
2531
2532 if (interface != NULL)
2533 bpf = bpf_open_live (interface, filter);
2534
2535 if (bpf < 0)
2536 {
2537 nasl_perror (lexic, "pcap_next: Could not get a bpf\n");
2538 if (alldevsp != NULL)
2539 pcap_freealldevs (alldevsp);
2540 return NULL;
2541 }
2542 else
2543 {
2544 int len;
2545 int dl_len = get_datalink_size (bpf_datalink (bpf));
2546 char *packet;
2547 struct timeval then, now;
2548
2549 retc = nasl_send (lexic);
2550 g_free (retc);
2551
2552 gettimeofday (&then, NULL);
2553 for (;;)
2554 {
2555 packet = (char *) bpf_next (bpf, &len);
2556
2557 if (packet != NULL)
2558 break;
2559
2560 if (timeout != 0)
2561 {
2562 gettimeofday (&now, NULL);
2563 if (now.tv_sec - then.tv_sec >= timeout)
2564 break;
2565 }
2566 }
2567
2568 if (packet)
2569 {
2570 if (v4_addr)
2571 {
2572 struct ip *ip;
2573 ip = (struct ip *) (packet + dl_len);
2574 sz = UNFIX (ip->ip_len);
2575 ret = g_malloc0 (sz);
2576
2577 is_ip = (ip->ip_v == 4);
2578 if (is_ip)
2579 {
2580 bcopy (ip, ret, sz);
2581 }
2582 else
2583 {
2584 sz = len - dl_len;
2585 bcopy (ip, ret, sz);
2586 }
2587 }
2588 else
2589 {
2590 struct ip6_hdr *ip;
2591 ip = (struct ip6_hdr *) (packet + dl_len);
2592 sz = UNFIX (ip->ip6_plen);
2593 ret6 = g_malloc0 (sz);
2594 is_ip = ((ip->ip6_flow & 0x3ffff) == 96);
2595 if (is_ip)
2596 {
2597 bcopy (ip, ret6, sz);
2598 }
2599 else
2600 {
2601 sz = len - dl_len;
2602 bcopy (ip, ret6, sz);
2603 }
2604 }
2605 }
2606 else
2607 {
2608 if (alldevsp != NULL)
2609 pcap_freealldevs (alldevsp);
2610 bpf_close (bpf);
2611 return NULL;
2612 }
2613 }
2614 bpf_close (bpf);
2616 if (v4_addr)
2617 retc->x.str_val = (char *) ret;
2618 else
2619 retc->x.str_val = (char *) ret6;
2620 retc->size = sz;
2621
2622 if (alldevsp != NULL)
2623 pcap_freealldevs (alldevsp);
2624
2625 return retc;
2626}
tree_cell * nasl_send(lex_ctxt *lexic)

References alloc_typed_cell(), bpf_close(), bpf_datalink(), bpf_next(), bpf_open_live(), CONST_DATA, get_datalink_size(), get_int_var_by_name(), get_str_var_by_name(), len, name, nasl_perror(), nasl_send(), plug_get_host_ip(), routethrough(), struct_lex_ctxt::script_infos, TC::size, TC::str_val, timeval(), UNFIX, v6_routethrough(), and TC::x.

Here is the call graph for this function:

◆ nasl_send_packet()

tree_cell * nasl_send_packet ( lex_ctxt * lexic)

Send a list of packets (passed as unnamed arguments) and listens to the answers. It returns a block made of all the sniffed “answers”.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]...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_broadcastDefault 0.
Returns
block made of all the sniffed “answers”.

Definition at line 2202 of file nasl_packet_forgery.c.

2203{
2204 tree_cell *retc = FAKE_CELL;
2205 int bpf = -1;
2206 u_char *answer;
2207 int answer_sz;
2208 struct sockaddr_in sockaddr;
2209 char *ip = NULL;
2210 struct ip *sip = NULL;
2211 int vi = 0, b, len = 0;
2212 int soc;
2213 int use_pcap = get_int_var_by_name (lexic, "pcap_active", 1);
2214 int to = get_int_var_by_name (lexic, "pcap_timeout", 5);
2215 char *filter = get_str_var_by_name (lexic, "pcap_filter");
2216 int dfl_len = get_int_var_by_name (lexic, "length", -1);
2217 int opt_on = 1;
2218 struct script_infos *script_infos = lexic->script_infos;
2219 struct in6_addr *dstip = plug_get_host_ip (script_infos);
2220 struct in_addr inaddr;
2221 int allow_broadcast = 0;
2222
2223 if (dstip == NULL || (IN6_IS_ADDR_V4MAPPED (dstip) != 1))
2224 return NULL;
2225 inaddr.s_addr = dstip->s6_addr32[3];
2226 soc = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
2227 if (soc < 0)
2228 return NULL;
2229 if (setsockopt (soc, IPPROTO_IP, IP_HDRINCL, (char *) &opt_on,
2230 sizeof (opt_on))
2231 < 0)
2232 perror ("setsockopt ");
2233
2234 while ((ip = get_str_var_by_num (lexic, vi)) != NULL)
2235 {
2236 allow_broadcast = get_int_var_by_name (lexic, "allow_broadcast", 0);
2237 int sz = get_var_size_by_num (lexic, vi);
2238 vi++;
2239
2240 if ((unsigned int) sz < sizeof (struct ip))
2241 {
2242 nasl_perror (lexic, "send_packet: packet is too short\n");
2243 continue;
2244 }
2245
2246 sip = (struct ip *) ip;
2247 if (use_pcap != 0 && bpf < 0)
2248 bpf = init_capture_device (sip->ip_dst, sip->ip_src, filter);
2249
2250 bzero (&sockaddr, sizeof (struct sockaddr_in));
2251 sockaddr.sin_family = AF_INET;
2252 sockaddr.sin_addr = sip->ip_dst;
2253
2254 if (allow_broadcast)
2255 {
2256 if (setsockopt (soc, SOL_SOCKET, SO_BROADCAST, &opt_on,
2257 sizeof (opt_on))
2258 < 0)
2259 perror ("setsockopt ");
2260 if (sockaddr.sin_addr.s_addr != INADDR_BROADCAST)
2261 allow_broadcast = 0;
2262 }
2263
2264 if (sockaddr.sin_addr.s_addr != inaddr.s_addr && !allow_broadcast)
2265 {
2266 char txt1[64], txt2[64];
2267 strncpy (txt1, inet_ntoa (sockaddr.sin_addr), sizeof (txt1));
2268 txt1[sizeof (txt1) - 1] = '\0';
2269 strncpy (txt2, inet_ntoa (inaddr), sizeof (txt2));
2270 txt2[sizeof (txt2) - 1] = '\0';
2271 nasl_perror (lexic,
2272 "send_packet: malicious or buggy script is trying to "
2273 "send packet to %s instead of designated target %s\n",
2274 txt1, txt2);
2275#if 1
2276 if (bpf >= 0)
2277 bpf_close (bpf);
2278 close (soc);
2279 return NULL;
2280#else
2281 sip->ip_dst = inaddr;
2282 sip->ip_sum = np_in_cksum ((u_short *) sip, sizeof (struct ip));
2283#endif
2284 }
2285
2286 if (dfl_len > 0 && dfl_len < sz)
2287 len = dfl_len;
2288 else
2289 len = sz;
2290
2291 b = sendto (soc, (u_char *) ip, len, 0, (struct sockaddr *) &sockaddr,
2292 sizeof (sockaddr));
2293 /* if(b < 0) perror("sendto "); */
2294 if (b >= 0 && use_pcap != 0 && bpf >= 0)
2295 {
2296 if (islocalhost (&sip->ip_dst))
2297 {
2298 answer = (u_char *) capture_next_packet (bpf, to, &answer_sz);
2299 while (answer != NULL
2300 && (!memcmp (answer, (char *) ip, sizeof (struct ip))))
2301 {
2302 g_free (answer);
2303 answer = (u_char *) capture_next_packet (bpf, to, &answer_sz);
2304 }
2305 }
2306 else
2307 answer = (u_char *) capture_next_packet (bpf, to, &answer_sz);
2308
2309 if (answer)
2310 {
2312 retc->x.str_val = (char *) answer;
2313 retc->size = answer_sz;
2314 break;
2315 }
2316 }
2317 }
2318 if (bpf >= 0)
2319 bpf_close (bpf);
2320 close (soc);
2321 return retc;
2322}
int init_capture_device(struct in_addr src, struct in_addr dest, char *filter)
Set up the pcap filter, and select the correct interface.
struct ip * capture_next_packet(int bpf, int timeout, int *sz)
int islocalhost(struct in_addr *addr)
Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
Definition pcap.c:271

References alloc_typed_cell(), bpf_close(), capture_next_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_capture_device(), islocalhost(), len, nasl_perror(), np_in_cksum(), 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:

◆ nasl_tcp_ping()

tree_cell * nasl_tcp_ping ( lex_ctxt * lexic)

Launches a “TCP ping” against the target host.

Tries to open a TCP connection and sees if anything comes back (SYN/ACK or RST).

Parameters
[in]lexicLexical context of NASL interpreter.
[in]portPort to ping. Internal list of common ports is used as default.
Returns
1 if Ping was successful, 0 else.

Definition at line 2048 of file nasl_packet_forgery.c.

2049{
2050 struct script_infos *script_infos = lexic->script_infos;
2051 struct in6_addr *dst = plug_get_host_ip (script_infos);
2052 if (IN6_IS_ADDR_V4MAPPED (dst) != 1)
2053 {
2054 tree_cell *retc = nasl_tcp_v6_ping (lexic);
2055 return retc;
2056 }
2057 int port;
2058 u_char packet[sizeof (struct ip) + sizeof (struct tcphdr)];
2059 int soc;
2060 struct ip *ip = (struct ip *) packet;
2061 struct tcphdr *tcp = (struct tcphdr *) (packet + sizeof (struct ip));
2062 struct in_addr src;
2063 struct sockaddr_in soca;
2064 int flag = 0;
2065 unsigned int i = 0;
2066 int bpf;
2067 char filter[255];
2068 tree_cell *retc;
2069 int opt = 1;
2070 struct timeval tv;
2071 int len;
2072#define rnd_tcp_port() (rand () % 65535 + 1024)
2073 int sports[] = {0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2074 0, 0, 0, 0, 0, 53, 0, 0, 20, 0, 25, 0, 0, 0};
2075 int ports[] = {139, 135, 445, 80, 22, 515, 23, 21, 6000, 1025,
2076 25, 111, 1028, 9100, 1029, 79, 497, 548, 5000, 1917,
2077 53, 161, 9001, 65535, 443, 113, 993, 8080};
2078 struct in_addr inaddr;
2079
2080 if (dst == NULL || (IN6_IS_ADDR_V4MAPPED (dst) != 1))
2081 return NULL;
2082 inaddr.s_addr = dst->s6_addr32[3];
2083 for (i = 0; i < sizeof (sports) / sizeof (int); i++)
2084 {
2085 if (sports[i] == 0)
2086 sports[i] = rnd_tcp_port ();
2087 }
2088
2089 soc = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
2090 if (soc < 0)
2091 return NULL;
2092 if (setsockopt (soc, IPPROTO_IP, IP_HDRINCL, (char *) &opt, sizeof (opt)) < 0)
2093 perror ("setsockopt ");
2094
2095 port = get_int_var_by_name (lexic, "port", -1);
2096 if (port == -1)
2098
2099 if (islocalhost (&inaddr) > 0)
2100 src.s_addr = dst->s6_addr32[3];
2101 else
2102 {
2103 bzero (&src, sizeof (src));
2104 routethrough (&inaddr, &src);
2105 }
2106
2107 snprintf (filter, sizeof (filter), "ip and src host %s", inet_ntoa (inaddr));
2108 bpf = init_capture_device (inaddr, src, filter);
2109
2110 if (islocalhost (&inaddr) != 0)
2111 flag++;
2112 else
2113 {
2114 for (i = 0; i < sizeof (sports) / sizeof (int) && !flag; i++)
2115 {
2116 bzero (packet, sizeof (packet));
2117 /* IP */
2118 ip->ip_hl = 5;
2119 ip->ip_off = FIX (0);
2120 ip->ip_v = 4;
2121 ip->ip_len = FIX (40);
2122 ip->ip_tos = 0;
2123 ip->ip_p = IPPROTO_TCP;
2124 ip->ip_id = rand ();
2125 ip->ip_ttl = 0x40;
2126 ip->ip_src = src;
2127 ip->ip_dst = inaddr;
2128 ip->ip_sum = 0;
2129 ip->ip_sum = np_in_cksum ((u_short *) ip, 20);
2130
2131 /* TCP */
2132 tcp->th_sport = port ? htons (rnd_tcp_port ()) : htons (sports[i]);
2133 tcp->th_flags = TH_SYN;
2134 tcp->th_dport = port ? htons (port) : htons (ports[i]);
2135 tcp->th_seq = rand ();
2136 tcp->th_ack = 0;
2137 tcp->th_x2 = 0;
2138 tcp->th_off = 5;
2139 tcp->th_win = 2048;
2140 tcp->th_urp = 0;
2141 tcp->th_sum = 0;
2142
2143 /* CKsum */
2144 {
2145 struct in_addr source, dest;
2146 struct pseudohdr pseudoheader;
2147 source.s_addr = ip->ip_src.s_addr;
2148 dest.s_addr = ip->ip_dst.s_addr;
2149
2150 bzero (&pseudoheader, 12 + sizeof (struct tcphdr));
2151 pseudoheader.saddr.s_addr = source.s_addr;
2152 pseudoheader.daddr.s_addr = dest.s_addr;
2153
2154 pseudoheader.protocol = 6;
2155 pseudoheader.length = htons (sizeof (struct tcphdr));
2156 bcopy ((char *) tcp, (char *) &pseudoheader.tcpheader,
2157 sizeof (struct tcphdr));
2158 tcp->th_sum = np_in_cksum ((unsigned short *) &pseudoheader,
2159 12 + sizeof (struct tcphdr));
2160 }
2161
2162 bzero (&soca, sizeof (soca));
2163 soca.sin_family = AF_INET;
2164 soca.sin_addr = ip->ip_dst;
2165 if (sendto (soc, (const void *) ip, 40, 0, (struct sockaddr *) &soca,
2166 sizeof (soca))
2167 < 0)
2168 g_warning ("sendto: %s", strerror (errno));
2169 tv.tv_sec = 0;
2170 tv.tv_usec = 100000;
2171 if (bpf >= 0 && bpf_next_tv (bpf, &len, &tv))
2172 flag++;
2173 }
2174 }
2175
2176 retc = alloc_typed_cell (CONST_INT);
2177 retc->x.i_val = flag;
2178 if (bpf >= 0)
2179 bpf_close (bpf);
2180 close (soc);
2181 return retc;
2182}
u_char * bpf_next_tv(int bpf, int *caplen, struct timeval *tv)
Definition bpf_share.c:119
#define rnd_tcp_port()
tree_cell * nasl_tcp_v6_ping(lex_ctxt *lexic)
Performs TCP Connect to test if host is alive.
unsigned int plug_get_host_open_port(struct script_infos *desc)
Definition plugutils.c:1323

References alloc_typed_cell(), bpf_close(), bpf_next_tv(), CONST_INT, pseudohdr::daddr, FIX, get_int_var_by_name(), TC::i_val, init_capture_device(), islocalhost(), len, pseudohdr::length, nasl_tcp_v6_ping(), np_in_cksum(), plug_get_host_ip(), plug_get_host_open_port(), pseudohdr::protocol, rnd_tcp_port, routethrough(), pseudohdr::saddr, struct_lex_ctxt::script_infos, pseudohdr::tcpheader, timeval(), and TC::x.

Referenced by nasl_end_denial(), and nasl_start_denial().

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

◆ set_ip_elements()

tree_cell * set_ip_elements ( lex_ctxt * lexic)

Modify the fields of a datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]ipIP datagram to set fields on.
[in]ip_hlIP header length in 32 bits words. 5 by default.
[in]ip_idDatagram ID. Random by default.
[in]ip_lenLength of the datagram. 20 plus the length of the data field by default.
[in]ip_offFragment offset in 64 bits words. 0 by default.
[in]ip_pIP protocol. 0 by default.
[in]ip_srcSource address in ASCII. NASL will convert it into an integer in network order.
[in]ip_sumPacket header checksum. It will be computed by default.
[in]ip_tosType of service field. 0 by default
[in]ip_ttlTime To Live field. 64 by default.
[in]ip_vIP version. 4 by default.
Returns
The modified IP datagram.

Definition at line 302 of file nasl_packet_forgery.c.

303{
304 struct ip *o_pkt = (struct ip *) get_str_var_by_name (lexic, "ip");
305 int size = get_var_size_by_name (lexic, "ip");
306 tree_cell *retc;
307 struct ip *pkt;
308 char *s;
309
310 if (o_pkt == NULL)
311 {
312 nasl_perror (lexic, "set_ip_elements: missing <ip> field\n");
313 return NULL;
314 }
315
316 pkt = (struct ip *) g_malloc0 (size);
317 bcopy (o_pkt, pkt, size);
318
319 pkt->ip_hl = get_int_var_by_name (lexic, "ip_hl", pkt->ip_hl);
320 pkt->ip_v = get_int_var_by_name (lexic, "ip_v", pkt->ip_v);
321 pkt->ip_tos = get_int_var_by_name (lexic, "ip_tos", pkt->ip_tos);
322 pkt->ip_len =
323 FIX (get_int_var_by_name (lexic, "ip_len", UNFIX (pkt->ip_len)));
324 pkt->ip_id = htons (get_int_var_by_name (lexic, "ip_id", pkt->ip_id));
325 pkt->ip_off =
326 FIX (get_int_var_by_name (lexic, "ip_off", UNFIX (pkt->ip_off)));
327 pkt->ip_ttl = get_int_var_by_name (lexic, "ip_ttl", pkt->ip_ttl);
328 pkt->ip_p = get_int_var_by_name (lexic, "ip_p", pkt->ip_p);
329
330 s = get_str_var_by_name (lexic, "ip_src");
331 if (s != NULL)
332 inet_aton (s, &pkt->ip_src);
333
334 pkt->ip_sum = htons (get_int_var_by_name (lexic, "ip_sum", 0));
335 if (pkt->ip_sum == 0)
336 pkt->ip_sum = np_in_cksum ((u_short *) pkt, sizeof (struct ip));
337
339 retc->size = size;
340 retc->x.str_val = (char *) pkt;
341
342 return retc;
343}

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:

◆ set_tcp_elements()

tree_cell * set_tcp_elements ( lex_ctxt * lexic)

Modify the TCP fields of a datagram.

Parameters
[in]lexicLexical context of NASL interpreter.
[in]tcpIP datagram.
[in]dataTCP data payload.
[in]th_ackAcknowledge number. NASL will convert it into network order if necessary.
[in]th_dportDestination port. NASL will convert it into network order if necessary.
[in]th_flagsTCP flags.
[in]th_offSize of the TCP header in 32 bits words.
[in]th_seqTCP sequence number. NASL will convert it into network order if necessary.
[in]th_sportSource port. NASL will convert it into network order if necessary.
[in]th_sumTCP checksum.
[in]th_urpUrgent pointer.
[in]th_winTCP window size. NASL will convert it into network order if necessary.
[in]th_x2Is a reserved field and should probably be left unchanged.
[in]update_ip_lenFlag (TRUE by default). If set, NASL will recompute the size field of the IP datagram.
Returns
The modified IP datagram.

Definition at line 929 of file nasl_packet_forgery.c.

930{
931 char *pkt = get_str_var_by_name (lexic, "tcp");
932 struct ip *ip = (struct ip *) pkt;
933 int pktsz = get_var_size_by_name (lexic, "tcp");
934 struct tcphdr *tcp;
935 tree_cell *retc;
936 char *data = get_str_var_by_name (lexic, "data");
937 int data_len = get_var_size_by_name (lexic, "data");
938 char *npkt;
939
940 if (!ip)
941 {
942 nasl_perror (lexic,
943 "set_tcp_elements: Invalid value for the argument 'tcp'\n");
944 return NULL;
945 }
946
947 if (ip->ip_hl * 4 > pktsz)
948 tcp =
949 (struct tcphdr *) (pkt
950 + 20); /* ip->ip_hl is bogus, we work around that */
951 else
952 tcp = (struct tcphdr *) (pkt + ip->ip_hl * 4);
953
954 if (pktsz < UNFIX (ip->ip_len))
955 return NULL;
956
957 if (data_len == 0)
958 {
959 data_len = UNFIX (ip->ip_len) - (ip->ip_hl * 4) - (tcp->th_off * 4);
960 data = (char *) ((char *) tcp + tcp->th_off * 4);
961 }
962
963 npkt = g_malloc0 (ip->ip_hl * 4 + tcp->th_off * 4 + data_len);
964 bcopy (pkt, npkt, UNFIX (ip->ip_len));
965
966 ip = (struct ip *) (npkt);
967 tcp = (struct tcphdr *) (npkt + ip->ip_hl * 4);
968
969 tcp->th_sport =
970 htons (get_int_var_by_name (lexic, "th_sport", ntohs (tcp->th_sport)));
971 tcp->th_dport =
972 htons (get_int_var_by_name (lexic, "th_dport", ntohs (tcp->th_dport)));
973 tcp->th_seq =
974 htonl (get_int_var_by_name (lexic, "th_seq", ntohl (tcp->th_seq)));
975 tcp->th_ack =
976 htonl (get_int_var_by_name (lexic, "th_ack", ntohl (tcp->th_ack)));
977 tcp->th_x2 = get_int_var_by_name (lexic, "th_x2", tcp->th_x2);
978 tcp->th_off = get_int_var_by_name (lexic, "th_off", tcp->th_off);
979 tcp->th_flags = get_int_var_by_name (lexic, "th_flags", tcp->th_flags);
980 tcp->th_win =
981 htons (get_int_var_by_name (lexic, "th_win", ntohs (tcp->th_win)));
982 tcp->th_sum = get_int_var_by_name (lexic, "th_sum", 0);
983 tcp->th_urp = get_int_var_by_name (lexic, "th_urp", tcp->th_urp);
984 bcopy (data, (char *) tcp + tcp->th_off * 4, data_len);
985
986 if (get_int_var_by_name (lexic, "update_ip_len", 1) != 0)
987 {
988 ip->ip_len = ip->ip_hl * 4 + tcp->th_off * 4 + data_len;
989 ip->ip_sum = 0;
990 ip->ip_sum = np_in_cksum ((u_short *) pkt, ip->ip_hl * 4);
991 }
992
993 if (tcp->th_sum == 0)
994 {
995 struct pseudohdr pseudoheader;
996 char *tcpsumdata = g_malloc0 (sizeof (struct pseudohdr) + data_len + 1);
997 struct in_addr source, dest;
998
999 source.s_addr = ip->ip_src.s_addr;
1000 dest.s_addr = ip->ip_dst.s_addr;
1001
1002 bzero (&pseudoheader, sizeof (pseudoheader));
1003 pseudoheader.saddr.s_addr = source.s_addr;
1004 pseudoheader.daddr.s_addr = dest.s_addr;
1005
1006 pseudoheader.protocol = IPPROTO_TCP;
1007 pseudoheader.length = htons (sizeof (struct tcphdr) + data_len);
1008 bcopy ((char *) tcp, (char *) &pseudoheader.tcpheader,
1009 sizeof (struct tcphdr));
1010 /* fill tcpsumdata with data to checksum */
1011 bcopy ((char *) &pseudoheader, tcpsumdata, sizeof (struct pseudohdr));
1012 bcopy ((char *) data, tcpsumdata + sizeof (struct pseudohdr), data_len);
1013 tcp->th_sum = np_in_cksum ((unsigned short *) tcpsumdata,
1014 sizeof (pseudoheader) + data_len);
1015 g_free (tcpsumdata);
1016 }
1017
1019 retc->size = (ip->ip_hl * 4) + (tcp->th_off * 4) + data_len;
1020 retc->x.str_val = npkt;
1021 return retc;
1022}

References alloc_typed_cell(), CONST_DATA, pseudohdr::daddr, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), pseudohdr::length, nasl_perror(), np_in_cksum(), pseudohdr::protocol, pseudohdr::saddr, TC::size, TC::str_val, pseudohdr::tcpheader, UNFIX, and TC::x.

Here is the call graph for this function:

◆ set_udp_elements()

tree_cell * set_udp_elements ( lex_ctxt * lexic)

Modify UDP fields of an IP datagram.

Parameters
[in]udpIP datagram to modify.
[in]dataPayload.
[in]uh_dportDestination port. NASL will convert it into network order if necessary.
[in]uh_sportSource port. NASL will convert it into network order if necessary.
[in]uh_sumUDP checksum.
[in]uh_ulenData length.
Returns
Modified IP datagram.

Definition at line 1620 of file nasl_packet_forgery.c.

1621{
1622 struct ip *ip = (struct ip *) get_str_var_by_name (lexic, "udp");
1623 unsigned int sz = get_var_size_by_name (lexic, "udp");
1624 char *data = get_str_var_by_name (lexic, "data");
1625 int data_len = get_var_size_by_name (lexic, "data");
1626
1627 if (ip != NULL)
1628 {
1629 char *pkt;
1630 struct udphdr *udp;
1631 tree_cell *retc;
1632 int old_len;
1633
1634 if (ip->ip_hl * 4 + sizeof (struct udphdr) > sz)
1635 return NULL;
1636
1637 if (data != NULL)
1638 {
1639 sz = ip->ip_hl * 4 + sizeof (struct udphdr) + data_len;
1640 pkt = g_malloc0 (sz);
1641 bcopy (ip, pkt, ip->ip_hl * 4 + sizeof (struct udphdr));
1642 }
1643 else
1644 {
1645 pkt = g_malloc0 (sz);
1646 bcopy (ip, pkt, sz);
1647 }
1648
1649 ip = (struct ip *) pkt;
1650 if (data != NULL)
1651 {
1652 ip->ip_len = FIX (sz);
1653 ip->ip_sum = 0;
1654 ip->ip_sum = np_in_cksum ((u_short *) ip, ip->ip_hl * 4);
1655 }
1656 udp = (struct udphdr *) (pkt + ip->ip_hl * 4);
1657
1658 udp->uh_sport =
1659 htons (get_int_var_by_name (lexic, "uh_sport", ntohs (udp->uh_sport)));
1660 udp->uh_dport =
1661 htons (get_int_var_by_name (lexic, "uh_dport", ntohs (udp->uh_dport)));
1662 old_len = ntohs (udp->uh_ulen);
1663 udp->uh_ulen =
1664 htons (get_int_var_by_name (lexic, "uh_ulen", ntohs (udp->uh_ulen)));
1665 udp->uh_sum = get_int_var_by_name (lexic, "uh_sum", 0);
1666
1667 if (data != NULL)
1668 {
1669 bcopy (data, pkt + ip->ip_hl * 4 + sizeof (struct udphdr), data_len);
1670 udp->uh_ulen = htons (sizeof (struct udphdr) + data_len);
1671 }
1672
1673 if (udp->uh_sum == 0)
1674 {
1676 struct in_addr source, dest;
1677 int len = old_len - sizeof (struct udphdr);
1678 char *udpsumdata;
1679 char *ptr = NULL;
1680
1681 if (data != NULL)
1682 {
1683 len = data_len;
1684 }
1685
1686 if (len > 0)
1687 {
1688 ptr = (char *) udp + sizeof (struct udphdr);
1689 }
1690
1691 udpsumdata = g_malloc0 (sizeof (struct pseudo_udp_hdr) + len + 1);
1692
1693 source.s_addr = ip->ip_src.s_addr;
1694 dest.s_addr = ip->ip_dst.s_addr;
1695
1696 bzero (&pseudohdr, sizeof (struct pseudo_udp_hdr));
1697 pseudohdr.saddr.s_addr = source.s_addr;
1698 pseudohdr.daddr.s_addr = dest.s_addr;
1699
1700 pseudohdr.proto = IPPROTO_UDP;
1701 pseudohdr.len = htons (sizeof (struct udphdr) + len);
1702 bcopy ((char *) udp, (char *) &pseudohdr.udpheader,
1703 sizeof (struct udphdr));
1704 bcopy ((char *) &pseudohdr, udpsumdata, sizeof (pseudohdr));
1705 if (ptr != NULL)
1706 {
1707 bcopy ((char *) ptr, udpsumdata + sizeof (pseudohdr), len);
1708 }
1709 udp->uh_sum = np_in_cksum ((unsigned short *) udpsumdata,
1710 12 + sizeof (struct udphdr) + len);
1711 g_free (udpsumdata);
1712 }
1714 retc->size = sz;
1715 retc->x.str_val = pkt;
1716 return retc;
1717 }
1718 else
1719 nasl_perror (lexic,
1720 "set_udp_elements: Invalid value for the argument 'udp'.");
1721
1722 return NULL;
1723}

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

Here is the call graph for this function: