OpenVAS Scanner  22.7.9
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. More...
 
tree_cellset_ip_elements (lex_ctxt *)
 Modify the fields of a datagram. More...
 
tree_cellget_ip_element (lex_ctxt *)
 Extracts a field from an IP datagram. More...
 
tree_celldump_ip_packet (lex_ctxt *)
 Dump IP datagrams. More...
 
tree_cellinsert_ip_options (lex_ctxt *)
 Add option datagram. More...
 
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: More...
 
tree_cellget_tcp_element (lex_ctxt *)
 Extracts TCP field from an IP datagram. More...
 
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. More...
 
tree_cellset_tcp_elements (lex_ctxt *)
 Modify the TCP fields of a datagram. More...
 
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. More...
 
tree_celldump_tcp_packet (lex_ctxt *)
 Dump the TCP part of a IP Datagram. More...
 
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: More...
 
tree_cellset_udp_elements (lex_ctxt *)
 Modify UDP fields of an IP datagram. More...
 
tree_celldump_udp_packet (lex_ctxt *)
 Dump the UDP part of a IP Datagram. More...
 
tree_cellget_udp_element (lex_ctxt *)
 Get an UDP element from a IP datagram. More...
 
tree_cellforge_icmp_packet (lex_ctxt *)
 Fill an IP datagram with ICMP data. More...
 
tree_cellget_icmp_element (lex_ctxt *)
 Get an ICMP element from a IP datagram. More...
 
tree_celldump_icmp_packet (lex_ctxt *)
 Dump the ICMP part of a IP Datagram. More...
 
tree_cellforge_igmp_packet (lex_ctxt *)
 Fills an IP datagram with IGMP data. More...
 
tree_cellnasl_tcp_ping (lex_ctxt *)
 Launches a “TCP ping” against the target host. More...
 
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”. More...
 
tree_cellnasl_pcap_next (lex_ctxt *)
 Listen to one packet and return it. More...
 
tree_cellnasl_send_capture (lex_ctxt *)
 Send a capture. More...
 

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 }

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 }

References FAKE_CELL, get_str_var_by_num(), and UNFIX.

Here is the call graph for this function:

◆ 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 }

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_options::mss, tcp_opt_mss::mss, tcp_options::sack_perm, tcp_options::tstamp, tcp_opt_tstamp::tstamp, UNFIX, tcp_options::wscale, and tcp_opt_wscale::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 
1834  retc = alloc_typed_cell (CONST_DATA);
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 }

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  }
2022  retc = alloc_typed_cell (CONST_DATA);
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 }

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 
126  retc = alloc_typed_cell (CONST_DATA);
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 }

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 
579  retc = alloc_typed_cell (CONST_DATA);
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  {
1483  struct pseudo_udp_hdr pseudohdr;
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 
1522  retc = alloc_typed_cell (CONST_DATA);
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 }

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  {
1887  retc = alloc_typed_cell (CONST_DATA);
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 }

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  {
252  retc = alloc_typed_cell (CONST_INT);
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 
274  retc = alloc_typed_cell (CONST_DATA);
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  {
709  retc = alloc_typed_cell (CONST_DATA);
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 
721  retc = alloc_typed_cell (CONST_INT);
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;
812  anon_nasl_var v;
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:
866  retc = alloc_typed_cell (CONST_INT);
867  retc->x.i_val = ntohs ((uint16_t) tcp_all_options->mss.mss);
868  break;
869  case TCPOPT_WINDOW:
870  retc = alloc_typed_cell (CONST_INT);
871  retc->x.i_val = tcp_all_options->wscale.wscale;
872  break;
873  case TCPOPT_SACK_PERMITTED:
874  retc = alloc_typed_cell (CONST_INT);
875  retc->x.i_val = tcp_all_options->sack_perm.kind ? 1 : 0;
876  break;
877  case TCPOPT_TIMESTAMP:
878  retc = alloc_typed_cell (DYN_ARRAY);
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 }

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_options::mss, tcp_opt_mss::mss, nasl_perror(), TC::ref_val, tcp_options::sack_perm, tcp_options::tstamp, tcp_opt_tstamp::tstamp, UNFIX, st_a_nasl_var::v, st_a_nasl_var::v_int, VAR2_INT, st_a_nasl_var::var_type, tcp_options::wscale, tcp_opt_wscale::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;
1581  retc = alloc_typed_cell (CONST_DATA);
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 
420  retc = alloc_typed_cell (CONST_DATA);
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 }

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 
1291  retc = alloc_typed_cell (CONST_DATA);
1292  retc->size = (ip->ip_hl * 4) + (tcp->th_off * 4) + data_len;
1293  retc->x.str_val = npkt;
1294  return retc;
1295 }

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_wscale::kind, tcp_opt_sack_perm::kind, tcp_opt_tstamp::kind, tcp_opt_mss::len, tcp_opt_wscale::len, tcp_opt_sack_perm::len, tcp_opt_tstamp::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);
2465  retc = alloc_typed_cell (CONST_DATA);
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 }

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(), 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);
2615  retc = alloc_typed_cell (CONST_DATA);
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 }

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(), 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  {
2311  retc = alloc_typed_cell (CONST_DATA);
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 }

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 }

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 
338  retc = alloc_typed_cell (CONST_DATA);
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 
1018  retc = alloc_typed_cell (CONST_DATA);
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  {
1675  struct pseudo_udp_hdr pseudohdr;
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  }
1713  retc = alloc_typed_cell (CONST_DATA);
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:
tcp_options::sack_perm
struct tcp_opt_sack_perm sack_perm
Definition: nasl_packet_forgery.c:523
pseudohdr::saddr
struct in_addr saddr
Definition: nasl_builtin_synscan.c:47
st_a_nasl_var
Definition: nasl_var.h:40
script_infos
Definition: scanneraux.h:29
tcp_opt_wscale
Definition: nasl_packet_forgery.c:499
CONST_DATA
@ CONST_DATA
Definition: nasl_tree.h:82
get_var_size_by_name
int get_var_size_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1138
igmp::cksum
unsigned short cksum
Definition: nasl_packet_forgery.c:1955
tcp_opt_wscale::len
uint8_t len
Definition: nasl_packet_forgery.c:501
plug_get_host_ip
struct in6_addr * plug_get_host_ip(struct script_infos *args)
Definition: plugutils.c:316
np_in_cksum
static int np_in_cksum(u_short *p, int n)
Definition: nasl_packet_forgery.c:50
bpf_open_live
int bpf_open_live(char *iface, char *filter)
Definition: bpf_share.c:39
TC::str_val
char * str_val
Definition: nasl_tree.h:103
tcp_options::mss
struct tcp_opt_mss mss
Definition: nasl_packet_forgery.c:521
tcp_opt_wscale::kind
uint8_t kind
Definition: nasl_packet_forgery.c:500
tcp_opt_sack_perm::len
uint8_t len
Definition: nasl_packet_forgery.c:508
FIX
#define FIX(n)
Definition: nasl_packet_forgery.c:39
tcp_options
Definition: nasl_packet_forgery.c:520
TC::x
union TC::@5 x
DYN_ARRAY
@ DYN_ARRAY
Definition: nasl_tree.h:90
pseudo_udp_hdr
Definition: nasl_packet_forgery.c:1422
v6_routethrough
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:841
FAKE_CELL
#define FAKE_CELL
Definition: nasl_tree.h:110
tcp_opt_sack_perm::kind
uint8_t kind
Definition: nasl_packet_forgery.c:507
pseudohdr::daddr
struct in_addr daddr
Definition: nasl_builtin_synscan.c:48
st_a_nasl_var::v
union st_a_nasl_var::@7 v
get_str_var_by_name
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1118
rnd_tcp_port
#define rnd_tcp_port()
bpf_close
void bpf_close(int bpf)
Definition: bpf_share.c:164
name
const char * name
Definition: nasl_init.c:411
st_nasl_array
Definition: nasl_var.h:33
zero
u_char zero
Definition: nasl_packet_forgery.c:2
VAR2_INT
@ VAR2_INT
Definition: nasl_var.h:16
tcp_options::wscale
struct tcp_opt_wscale wscale
Definition: nasl_packet_forgery.c:522
plug_get_host_open_port
unsigned int plug_get_host_open_port(struct script_infos *desc)
Definition: plugutils.c:1220
init_capture_device
int init_capture_device(struct in_addr src, struct in_addr dest, char *filter)
Set up the pcap filter, and select the correct interface.
Definition: capture_packet.c:31
nasl_perror
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:111
bpf_next_tv
u_char * bpf_next_tv(int bpf, int *caplen, struct timeval *tv)
Definition: bpf_share.c:119
add_var_to_array
int add_var_to_array(nasl_array *a, char *name, const anon_nasl_var *v)
Definition: nasl_var.c:1277
TC::size
int size
Definition: nasl_tree.h:99
tcp_opt_tstamp::tstamp
uint32_t tstamp
Definition: nasl_packet_forgery.c:515
tcp_opt_tstamp::len
uint8_t len
Definition: nasl_packet_forgery.c:514
len
uint8_t len
Definition: nasl_packet_forgery.c:1
get_int_var_by_name
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition: nasl_var.c:1104
tcp_opt_sack_perm
Definition: nasl_packet_forgery.c:506
igmp::group
struct in_addr group
Definition: nasl_packet_forgery.c:1956
tcp_opt_mss::mss
uint16_t mss
Definition: nasl_packet_forgery.c:495
islocalhost
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:261
igmp
Definition: nasl_packet_forgery.c:1952
tcp_opt_mss
Definition: nasl_packet_forgery.c:492
TC::ref_val
void * ref_val
Definition: nasl_tree.h:105
get_int_var_by_num
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1097
get_str_var_by_num
char * get_str_var_by_num(lex_ctxt *, int)
Definition: nasl_var.c:1111
st_a_nasl_var::var_type
int var_type
Definition: nasl_var.h:41
tcp_opt_wscale::wscale
uint8_t wscale
Definition: nasl_packet_forgery.c:502
bpf_datalink
int bpf_datalink(int bpf)
Definition: bpf_share.c:158
timeval
static struct timeval timeval(unsigned long val)
Definition: nasl_builtin_synscan.c:94
struct_lex_ctxt::script_infos
struct script_infos * script_infos
Definition: nasl_lex_ctxt.h:30
capture_next_packet
struct ip * capture_next_packet(int bpf, int timeout, int *sz)
Definition: capture_packet.c:157
pseudohdr
Definition: nasl_builtin_synscan.c:46
TC
Definition: nasl_tree.h:94
get_datalink_size
int get_datalink_size(int datalink)
Definition: pcap.c:288
tcp_opt_tstamp::e_tstamp
uint32_t e_tstamp
Definition: nasl_packet_forgery.c:516
get_tcp_options
static void get_tcp_options(char *options, struct tcp_options *tcp_all_options)
Extract all TCP option from an IP datagram.
Definition: nasl_packet_forgery.c:733
nasl_tcp_v6_ping
tree_cell * nasl_tcp_v6_ping(lex_ctxt *lexic)
Performs TCP Connect to test if host is alive.
Definition: nasl_packet_forgery_v6.c:2177
CONST_INT
@ CONST_INT
Definition: nasl_tree.h:79
get_var_size_by_num
int get_var_size_by_num(lex_ctxt *, int)
Definition: nasl_var.c:1145
nasl_send
tree_cell * nasl_send(lex_ctxt *lexic)
Definition: nasl_socket.c:960
tcp_opt_tstamp::kind
uint8_t kind
Definition: nasl_packet_forgery.c:513
tcp_opt_tstamp
Definition: nasl_packet_forgery.c:512
bpf_next
u_char * bpf_next(int bpf, int *caplen)
Definition: bpf_share.c:150
tcp_opt_mss::kind
uint8_t kind
Definition: nasl_packet_forgery.c:493
tcp_options::tstamp
struct tcp_opt_tstamp tstamp
Definition: nasl_packet_forgery.c:524
st_a_nasl_var::v_int
long int v_int
Definition: nasl_var.h:48
tcp_opt_mss::len
uint8_t len
Definition: nasl_packet_forgery.c:494
UNFIX
#define UNFIX(n)
Definition: nasl_packet_forgery.c:40
alloc_typed_cell
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:28
routethrough
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:1060
code
#define code
igmp::code
unsigned char code
Definition: nasl_packet_forgery.c:1954
igmp::type
unsigned char type
Definition: nasl_packet_forgery.c:1953
TC::i_val
long int i_val
Definition: nasl_tree.h:104