#ifndef TCP_PACKET_H #define TCP_PACKET_H #include #include #include "massip-addr.h" struct PayloadsUDP; struct MassVulnCheck; struct TemplateOptions; /** * Does a regression test of this module. * @return * 1 on failure * 0 on success */ int template_selftest(void); enum TemplateProtocol { Proto_TCP, Proto_UDP, Proto_SCTP, Proto_ICMP_ping, Proto_ICMP_timestamp, Proto_ARP, Proto_Oproto, Proto_VulnCheck, //Proto_IP, //Proto_Custom, Proto_Count }; struct TemplatePayload { unsigned length; unsigned checksum; unsigned char buf[1500]; }; unsigned udp_checksum2(const unsigned char *px, unsigned offset_ip, unsigned offset_tcp, size_t tcp_length); /** * Describes a packet template. The scan packets we transmit are based on a * a template containing most of the data, and we fill in just the necessary * bits, like the destination IP address and port */ struct TemplatePacket { struct { unsigned length; unsigned offset_ip; unsigned offset_tcp; unsigned offset_app; unsigned char *packet; unsigned checksum_ip; unsigned checksum_tcp; unsigned ip_id; } ipv4; struct { unsigned length; unsigned offset_ip; unsigned offset_tcp; unsigned offset_app; unsigned char *packet; unsigned checksum_ip; unsigned checksum_tcp; unsigned ip_id; } ipv6; enum TemplateProtocol proto; struct PayloadsUDP *payloads; }; /** * We can run multiple types of scans (TCP, UDP, vulns, etc.) at the same * time. Therefore, instead of one packet prototype for all scans, we have * a set of prototypes/templates. */ struct TemplateSet { unsigned count; struct MassVulnCheck *vulncheck; uint64_t entropy; struct TemplatePacket pkts[Proto_Count]; }; struct TemplateSet templ_copy(const struct TemplateSet *templ); /** * Initialize the "template" packets. As we spew out probes, we simply make * minor adjustments to the template, such as changing the target IP * address or port number * * @param templset * The template we are creating. * @param source_ip * Our own IP address that we send packets from. The caller will have * retrieved this automatically from the network interface/adapter, or * the user will have set this with --source-ip parameter. * @param source_mac * Our own MAC address. Gotten automatically from the network adapter, * or on the commandline with --source-mac parameter * @param router_mac * The MAC address of the local router/gateway, which will be placed in * the Ethernet destination address field. This is gotten by ARPing * the local router, or by --router-mac configuration parameter. * @param data_link * The OSI layer 2 protocol, as defined in standard. * 1 = Ethernet * 12 = Raw IP (no data link) */ void template_packet_init( struct TemplateSet *templset, macaddress_t source_mac, macaddress_t router_mac_ipv4, macaddress_t router_mac_ipv6, struct PayloadsUDP *udp_payloads, struct PayloadsUDP *oproto_payloads, int data_link, uint64_t entropy, const struct TemplateOptions *templ_opts); /** * Sets the target/destination IP address of the packet, the destination port * number, and other bits of interest about the packet, such as a unique * sequence number. The template can contain things like IP or TCP options * with specific values. The program contains several built-in templates, * but they can also be read from a file. * * @param templset * A template created by "template_packet_init()" and further modified * by various configuration parameters. * @param ip * The target/destination IPv4 address. * @param port * The TCP port number, or port number from another protocol that will * be shifted into the appropriate range. We actually build six base * templates, one for each of these six protocols. * [ 0.. 65535] = TCP port number * [ 65536..131071] = UDP port number * [131072..196607] = SCTP port number * [ 196608 ] = ICMP * [ 196609 ] = ARP * [ 196610 ] = IP * [ more ] = custom * @param seqno * On TCP, this will be the desired sequence number, which the caller * will create from SYN-cookies. Other protocols may use this in a * different manner. For example, if the UDP port is 161, then * this will be the transaction ID of the SNMP request template. */ void template_set_target_ipv4( struct TemplateSet *templset, ipv4address ip_them, unsigned port_them, ipv4address ip_me, unsigned port_me, unsigned seqno, unsigned char *px, size_t sizeof_px, size_t *r_length); void template_set_target_ipv6( struct TemplateSet *templset, ipv6address ip_them, unsigned port_them, ipv6address ip_me, unsigned port_me, unsigned seqno, unsigned char *px, size_t sizeof_px, size_t *r_length); /** * Create a TCP packet containing a payload, based on the original * template used for the SYN */ size_t tcp_create_packet( struct TemplatePacket *pkt, ipaddress ip_them, unsigned port_them, ipaddress ip_me, unsigned port_me, unsigned seqno, unsigned ackno, unsigned flags, const unsigned char *payload, size_t payload_length, unsigned char *px, size_t px_length); /** * Set's the TCP "window" field. The purpose is to cause the recipient * to fragment data on the response, thus evading IDS that triggers on * out going packets */ void tcp_set_window(unsigned char *px, size_t px_length, unsigned window); void template_set_ttl(struct TemplateSet *tmplset, unsigned ttl); void template_set_vlan(struct TemplateSet *tmplset, unsigned vlan); #endif