summaryrefslogtreecommitdiffstats
path: root/tcpip.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tcpip.h384
1 files changed, 384 insertions, 0 deletions
diff --git a/tcpip.h b/tcpip.h
new file mode 100644
index 0000000..dd86c69
--- /dev/null
+++ b/tcpip.h
@@ -0,0 +1,384 @@
+
+/***************************************************************************
+ * tcpip.h -- Various functions relating to low level TCP/IP handling, *
+ * including sending raw packets, routing, printing packets, reading from *
+ * libpcap, etc. *
+ * *
+ ***********************IMPORTANT NMAP LICENSE TERMS************************
+ *
+ * The Nmap Security Scanner is (C) 1996-2023 Nmap Software LLC ("The Nmap
+ * Project"). Nmap is also a registered trademark of the Nmap Project.
+ *
+ * This program is distributed under the terms of the Nmap Public Source
+ * License (NPSL). The exact license text applying to a particular Nmap
+ * release or source code control revision is contained in the LICENSE
+ * file distributed with that version of Nmap or source code control
+ * revision. More Nmap copyright/legal information is available from
+ * https://nmap.org/book/man-legal.html, and further information on the
+ * NPSL license itself can be found at https://nmap.org/npsl/ . This
+ * header summarizes some key points from the Nmap license, but is no
+ * substitute for the actual license text.
+ *
+ * Nmap is generally free for end users to download and use themselves,
+ * including commercial use. It is available from https://nmap.org.
+ *
+ * The Nmap license generally prohibits companies from using and
+ * redistributing Nmap in commercial products, but we sell a special Nmap
+ * OEM Edition with a more permissive license and special features for
+ * this purpose. See https://nmap.org/oem/
+ *
+ * If you have received a written Nmap license agreement or contract
+ * stating terms other than these (such as an Nmap OEM license), you may
+ * choose to use and redistribute Nmap under those terms instead.
+ *
+ * The official Nmap Windows builds include the Npcap software
+ * (https://npcap.com) for packet capture and transmission. It is under
+ * separate license terms which forbid redistribution without special
+ * permission. So the official Nmap Windows builds may not be redistributed
+ * without special permission (such as an Nmap OEM license).
+ *
+ * Source is provided to this software because we believe users have a
+ * right to know exactly what a program is going to do before they run it.
+ * This also allows you to audit the software for security holes.
+ *
+ * Source code also allows you to port Nmap to new platforms, fix bugs, and add
+ * new features. You are highly encouraged to submit your changes as a Github PR
+ * or by email to the dev@nmap.org mailing list for possible incorporation into
+ * the main distribution. Unless you specify otherwise, it is understood that
+ * you are offering us very broad rights to use your submissions as described in
+ * the Nmap Public Source License Contributor Agreement. This is important
+ * because we fund the project by selling licenses with various terms, and also
+ * because the inability to relicense code has caused devastating problems for
+ * other Free Software projects (such as KDE and NASM).
+ *
+ * The free version of Nmap is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties,
+ * indemnification and commercial support are all available through the
+ * Npcap OEM program--see https://nmap.org/oem/
+ *
+ ***************************************************************************/
+
+/* $Id$ */
+
+
+#ifndef TCPIP_H
+#define TCPIP_H
+
+#include "nbase.h"
+
+#include <pcap.h>
+
+class Target;
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+
+int nmap_raw_socket();
+
+/* Used for tracing all packets sent or received (eg the
+ --packet-trace option) */
+
+class PacketTrace {
+ public:
+ static const int SENT=1; /* These two values must not be changed */
+ static const int RCVD=2;
+ typedef int pdirection;
+ /* Takes an IP PACKET and prints it if packet tracing is enabled.
+ 'packet' must point to the IPv4 header. The direction must be
+ PacketTrace::SENT or PacketTrace::RCVD . Optional 'now' argument
+ makes this function slightly more efficient by avoiding a gettimeofday()
+ call. */
+ static void trace(pdirection pdir, const u8 *packet, u32 len,
+ struct timeval *now=NULL);
+/* Adds a trace entry when a connect() is attempted if packet tracing
+ is enabled. Pass IPPROTO_TCP or IPPROTO_UDP as the protocol. The
+ sock may be a sockaddr_in or sockaddr_in6. The return code of
+ connect is passed in connectrc. If the return code is -1, get the
+ errno and pass that as connect_errno. */
+ static void traceConnect(u8 proto, const struct sockaddr *sock,
+ int socklen, int connectrc, int connect_errno,
+ const struct timeval *now);
+ /* Takes an ARP PACKET (including ethernet header) and prints it if
+ packet tracing is enabled. 'frame' must point to the 14-byte
+ ethernet header (e.g. starting with destination addr). The
+ direction must be PacketTrace::SENT or PacketTrace::RCVD .
+ Optional 'now' argument makes this function slightly more
+ efficient by avoiding a gettimeofday() call. */
+ static void traceArp(pdirection pdir, const u8 *frame, u32 len,
+ struct timeval *now);
+ static void traceND(pdirection pdir, const u8 *frame, u32 len,
+ struct timeval *now);
+};
+
+class PacketCounter {
+ public:
+ PacketCounter() : sendPackets(0), sendBytes(0), recvPackets(0), recvBytes(0) {}
+#if WIN32
+ unsigned __int64
+#else
+ unsigned long long
+#endif
+ sendPackets, sendBytes, recvPackets, recvBytes;
+};
+
+
+/* Some systems might not have this */
+#ifndef IPPROTO_IGMP
+#define IPPROTO_IGMP 2
+#endif
+
+/* Prototypes */
+/* Converts an IP address given in a sockaddr_storage to an IPv4 or
+ IPv6 IP address string. Since a static buffer is returned, this is
+ not thread-safe and can only be used once in calls like printf()
+*/
+const char *inet_socktop(const struct sockaddr_storage *ss);
+
+/* Tries to resolve the given name (or literal IP) into a sockaddr
+ structure. This function calls getaddrinfo and returns the same
+ addrinfo linked list that getaddrinfo produces. Returns NULL for any
+ error or failure to resolve. */
+struct addrinfo *resolve_all(const char *hostname, int pf);
+
+/* Takes a destination address (dst) and tries to determine the
+ source address and interface necessary to route to this address.
+ If no route is found, false is returned and rnfo is undefined. If
+ a route is found, true is returned and rnfo is filled in with all
+ of the routing details. This function takes into account -S and -e
+ options set by user (o.spoofsource, o.device) */
+int nmap_route_dst(const struct sockaddr_storage *dst, struct route_nfo *rnfo);
+
+/* Send a pre-built IPv4 or IPv6 packet */
+int send_ip_packet(int sd, const struct eth_nfo *eth,
+ const struct sockaddr_storage *dst,
+ const u8 *packet, unsigned int packetlen);
+
+/* Builds an IP packet (including an IP header) by packing the fields
+ with the given information. It allocates a new buffer to store the
+ packet contents, and then returns that buffer. The packet is not
+ actually sent by this function. Caller must delete the buffer when
+ finished with the packet. The packet length is returned in
+ packetlen, which must be a valid int pointer. */
+u8 *build_ip_raw(const struct in_addr *source, const struct in_addr *victim,
+ u8 proto,
+ int ttl, u16 ipid, u8 tos, bool df,
+ const u8* ipopt, int ipoptlen,
+ const char *data, u16 datalen,
+ u32 *packetlen);
+
+u8 *build_ipv6_raw(const struct in6_addr *source,
+ const struct in6_addr *victim, u8 tc, u32 flowlabel,
+ u8 nextheader, int hoplimit,
+ const char *data, u16 datalen, u32 *outpacketlen);
+
+/* Builds a TCP packet (including an IP header) by packing the fields
+ with the given information. It allocates a new buffer to store the
+ packet contents, and then returns that buffer. The packet is not
+ actually sent by this function. Caller must delete the buffer when
+ finished with the packet. The packet length is returned in
+ packetlen, which must be a valid int pointer. */
+u8 *build_tcp_raw(const struct in_addr *source, const struct in_addr *victim,
+ int ttl, u16 ipid, u8 tos, bool df,
+ const u8* ipopt, int ipoptlen,
+ u16 sport, u16 dport,
+ u32 seq, u32 ack, u8 reserved, u8 flags, u16 window, u16 urp,
+ const u8 *options, int optlen,
+ const char *data, u16 datalen,
+ u32 *packetlen);
+
+u8 *build_tcp_raw_ipv6(const struct in6_addr *source,
+ const struct in6_addr *victim, u8 tc, u32 flowlabel,
+ u8 hoplimit, u16 sport, u16 dport, u32 seq, u32 ack,
+ u8 reserved, u8 flags, u16 window, u16 urp,
+ const u8 *tcpopt, int tcpoptlen, const char *data,
+ u16 datalen, u32 *packetlen);
+
+/* Build and send a raw tcp packet. If TTL is -1, a partially random
+ (but likely large enough) one is chosen */
+int send_tcp_raw(int sd, const struct eth_nfo *eth,
+ const struct in_addr *source, const struct in_addr *victim,
+ int ttl, bool df,
+ u8* ipopt, int ipoptlen,
+ u16 sport, u16 dport,
+ u32 seq, u32 ack, u8 reserved, u8 flags, u16 window, u16 urp,
+ u8 *options, int optlen,
+ const char *data, u16 datalen);
+
+int send_tcp_raw_decoys(int sd, const struct eth_nfo *eth,
+ const struct in_addr *victim,
+ int ttl, bool df,
+ u8* ipopt, int ipoptlen,
+ u16 sport, u16 dport,
+ u32 seq, u32 ack, u8 reserved, u8 flags, u16 window, u16 urp,
+ u8 *options, int optlen,
+ const char *data, u16 datalen);
+
+/* Builds a UDP packet (including an IP header) by packing the fields
+ with the given information. It allocates a new buffer to store the
+ packet contents, and then returns that buffer. The packet is not
+ actually sent by this function. Caller must delete the buffer when
+ finished with the packet. The packet length is returned in
+ packetlen, which must be a valid int pointer. */
+u8 *build_udp_raw(const struct in_addr *source, const struct in_addr *victim,
+ int ttl, u16 ipid, u8 tos, bool df,
+ u8* ipopt, int ipoptlen,
+ u16 sport, u16 dport,
+ const char *data, u16 datalen,
+ u32 *packetlen);
+
+u8 *build_udp_raw_ipv6(const struct in6_addr *source,
+ const struct in6_addr *victim, u8 tc, u32 flowlabel,
+ u8 hoplimit, u16 sport, u16 dport,
+ const char *data, u16 datalen, u32 *packetlen);
+
+int send_udp_raw(int sd, const struct eth_nfo *eth,
+ struct in_addr *source, const struct in_addr *victim,
+ int ttl, u16 ipid,
+ u8* ipopt, int ipoptlen,
+ u16 sport, u16 dport,
+ const char *data, u16 datalen);
+
+int send_udp_raw_decoys(int sd, const struct eth_nfo *eth,
+ const struct in_addr *victim,
+ int ttl, u16 ipid,
+ u8* ipops, int ip,
+ u16 sport, u16 dport,
+ const char *data, u16 datalen);
+
+/* Builds an SCTP packet (including an IP header) by packing the fields
+ with the given information. It allocates a new buffer to store the
+ packet contents, and then returns that buffer. The packet is not
+ actually sent by this function. Caller must delete the buffer when
+ finished with the packet. The packet length is returned in
+ packetlen, which must be a valid int pointer. */
+u8 *build_sctp_raw(const struct in_addr *source, const struct in_addr *victim,
+ int ttl, u16 ipid, u8 tos, bool df,
+ u8* ipopt, int ipoptlen,
+ u16 sport, u16 dport,
+ u32 vtag, char *chunks, int chunkslen,
+ const char *data, u16 datalen,
+ u32 *packetlen);
+
+u8 *build_sctp_raw_ipv6(const struct in6_addr *source,
+ const struct in6_addr *victim, u8 tc, u32 flowlabel,
+ u8 hoplimit, u16 sport, u16 dport, u32 vtag,
+ char *chunks, int chunkslen, const char *data, u16 datalen,
+ u32 *packetlen);
+
+/* Builds an ICMP packet (including an IP header) by packing the
+ fields with the given information. It allocates a new buffer to
+ store the packet contents, and then returns that buffer. The
+ packet is not actually sent by this function. Caller must delete
+ the buffer when finished with the packet. The packet length is
+ returned in packetlen, which must be a valid int pointer. The
+ id/seq will be converted to network byte order (if it differs from
+ HBO) */
+u8 *build_icmp_raw(const struct in_addr *source, const struct in_addr *victim,
+ int ttl, u16 ipid, u8 tos, bool df,
+ u8* ipopt, int ipoptlen,
+ u16 seq, unsigned short id, u8 ptype, u8 pcode,
+ const char *data, u16 datalen, u32 *packetlen);
+
+u8 *build_icmpv6_raw(const struct in6_addr *source,
+ const struct in6_addr *victim, u8 tc, u32 flowlabel,
+ u8 hoplimit, u16 seq, u16 id, u8 ptype, u8 pcode,
+ const char *data, u16 datalen, u32 *packetlen);
+
+/* Builds an IGMP packet (including an IP header) by packing the fields
+ with the given information. It allocates a new buffer to store the
+ packet contents, and then returns that buffer. The packet is not
+ actually sent by this function. Caller must delete the buffer when
+ finished with the packet. The packet length is returned in packetlen,
+ which must be a valid int pointer.
+ */
+u8 *build_igmp_raw(const struct in_addr *source, const struct in_addr *victim,
+ int ttl, u16 ipid, u8 tos, bool df,
+ u8* ipopt, int ipoptlen,
+ u8 ptype, u8 pcode,
+ const char *data, u16 datalen, u32 *packetlen);
+
+
+// Returns whether the packet receive time value obtained from libpcap
+// (and thus by readip_pcap()) should be considered valid. When
+// invalid (Windows and Amiga), readip_pcap returns the time you called it.
+bool pcap_recv_timeval_valid();
+
+/* Prints stats from a pcap descriptor (number of received and dropped
+ packets). */
+void pcap_print_stats(int logt, pcap_t *pd);
+
+
+
+/* A simple function I wrote to help in debugging, shows the important fields
+ of a TCP packet*/
+int readtcppacket(const u8 *packet, int readdata);
+int readudppacket(const u8 *packet, int readdata);
+
+/* Fill buf (up to buflen -- truncate if necessary but always
+ terminate) with a short representation of the packet stats.
+ Returns buf. Aborts if there is a problem. */
+char *getFinalPacketStats(char *buf, int buflen);
+
+/* This function tries to determine the target's ethernet MAC address
+ from a received packet as follows:
+ 1) If linkhdr is an ethernet header, grab the src mac (otherwise give up)
+ 2) If overwrite is 0 and a MAC is already set for this target, give up.
+ 3) If the packet source address is not the target, give up.
+ 4) Use the routing table to try to determine rather target is
+ directly connected to the src host running Nmap. If it is, set the MAC.
+
+ This function returns 0 if it ends up setting the MAC, nonzero otherwise
+*/
+
+int setTargetMACIfAvailable(Target *target, struct link_header *linkhdr,
+ const struct sockaddr_storage *src, int overwrite);
+
+/* This function ensures that the next hop MAC address for a target is
+ filled in. This address is the target's own MAC if it is directly
+ connected, and the next hop mac otherwise. Returns true if the
+ address is set when the function ends, false if not. This function
+ firt checks if it is already set, if not it tries the arp cache,
+ and if that fails it sends an ARP request itself. This should be called
+ after an ARP scan if many directly connected machines are involved. */
+bool setTargetNextHopMAC(Target *target);
+
+bool getNextHopMAC(const char *iface, const u8 *srcmac, const struct sockaddr_storage *srcss,
+ const struct sockaddr_storage *dstss, u8 *dstmac);
+
+/* If rcvdtime is non-null and a packet is returned, rcvd will be
+ filled with the time that packet was captured from the wire by
+ pcap. If linknfo is not NULL, lnkinfo->headerlen and
+ lnkinfo->header will be filled with the appropriate values. */
+const u8 *readipv4_pcap(pcap_t *pd, unsigned int *len, long to_usec,
+ struct timeval *rcvdtime, struct link_header *linknfo, bool validate);
+
+const u8 *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec,
+ struct timeval *rcvdtime, struct link_header *linknfo, bool validate);
+
+/* Examines the given tcp packet and obtains the TCP timestamp option
+ information if available. Note that the CALLER must ensure that
+ "tcp" contains a valid header (in particular the th_off must be the
+ true packet length and tcp must contain it). If a valid timestamp
+ option is found in the header, nonzero is returned and the
+ 'timestamp' and 'echots' parameters are filled in with the
+ appropriate value (if non-null). Otherwise 0 is returned and the
+ parameters (if non-null) are filled with 0. Remember that the
+ correct way to check for errors is to look at the return value
+ since a zero ts or echots could possibly be valid. */
+int gettcpopt_ts(const struct tcp_hdr *tcp, u32 *timestamp, u32 *echots);
+
+/* Maximize the receive buffer of a socket descriptor (up to 500K) */
+void max_rcvbuf(int sd);
+
+/* Do a receive (recv()) on a socket and stick the results (upt to
+ len) into buf . Give up after 'seconds'. Returns the number of
+ bytes read (or -1 in the case of an error. It only does one recv
+ (it will not keep going until len bytes are read). If timedout is
+ not NULL, it will be set to zero (no timeout occurred) or 1 (it
+ did). */
+int recvtime(int sd, char *buf, int len, int seconds, int *timedout);
+
+#endif /*TCPIP_H*/
+