Logo Search packages:      
Sourcecode: nemesis version File versions  Download package

nemesis-proto_tcp.c

/*
 * THE NEMESIS PROJECT
 * Copyright (C) 1999, 2000, 2001 Mark Grimes <mark@stateful.net>
 * Copyright (C) 2001 - 2003 Jeff Nathan <jeff@snort.org>
 *
 * nemesis-proto_tcp.c (TCP Packet Generator)
 *
 */

#include "nemesis-tcp.h"
#include "nemesis.h"

int buildtcp(ETHERhdr *eth, IPhdr *ip, TCPhdr *tcp, PayloadData *pd, 
        OptionsData *ipod, OptionsData *tcpod, char *device)
{
   int n;
   u_int32_t tcp_packetlen = 0, tcp_meta_packetlen = 0;
   static u_int8_t *pkt;
   static int sockfd = -1;
   struct libnet_link_int *l2 = NULL;
#if !defined(WIN32)
    int sockbuff = IP_MAXPACKET;
#endif

    if (pd->payload == NULL)
        pd->payload_s = 0;
    if (ipod->options == NULL)
        ipod->options_s = 0;
    if (tcpod->options == NULL)
        tcpod->options_s = 0;

    if (got_link)    /* data link layer transport */
    {
        if ((l2 = libnet_open_link_interface(device, errbuf)) == NULL)
        {
            fprintf(stderr, 
                    "ERROR: Unable to open layer 2 device for writing: "
                    "%s.\n", errbuf);
            return -1;
        }
    }
    else
    {
        sockfd = libnet_open_raw_sock(IPPROTO_RAW);
        if (sockfd < 0)
        {
            fprintf(stderr, "ERROR: Unable to allocate a socket descriptor.\n");
            return -1;
        }
#if !defined(WIN32)
        if ((setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const void *)&sockbuff, 
                sizeof(sockbuff))) < 0)
        {
            fprintf(stderr, "ERROR: setsockopt() failed.\n");
            return -1;
        }
#endif
    }

    tcp_packetlen = ((got_link == 1) ? LIBNET_ETH_H : 0) + LIBNET_IP_H + 
            LIBNET_TCP_H + pd->payload_s + ipod->options_s + tcpod->options_s;

    tcp_meta_packetlen = tcp_packetlen - (((got_link == 1) ? LIBNET_ETH_H : 0) +
            LIBNET_IP_H);

    if (libnet_init_packet(tcp_packetlen, &pkt) == -1)
    {
        fprintf(stderr, "ERROR: Unable to allocate packet memory.\n");
        return -1;
    }

    if (got_link)
        libnet_build_ethernet(eth->ether_dhost, eth->ether_shost, ETHERTYPE_IP,
                NULL, 0, pkt);

    libnet_build_ip(tcp_meta_packetlen, ip->ip_tos, ip->ip_id, ip->ip_off, 
            ip->ip_ttl, ip->ip_p, ip->ip_src.s_addr, ip->ip_dst.s_addr, 
            NULL, 0, pkt + ((got_link == 1) ? LIBNET_ETH_H : 0));

    libnet_build_tcp(tcp->th_sport, tcp->th_dport, tcp->th_seq, 
            tcp->th_ack, tcp->th_flags, tcp->th_win, tcp->th_urp, 
            pd->payload, pd->payload_s, pkt + ((got_link == 1) ? LIBNET_ETH_H :
            0) + LIBNET_IP_H);

    if (got_ipoptions)
    {
        if ((libnet_insert_ipo((struct ipoption *)ipod->options, 
                ipod->options_s, pkt + ((got_link == 1) ? LIBNET_ETH_H : 
                0))) == -1)
        {
            fprintf(stderr, "ERROR: Unable to add IP options, discarding "
                    "them.\n");
        }
    }

    if (got_tcpoptions)
    {
        if ((libnet_insert_tcpo((struct tcpoption *)tcpod->options, 
                tcpod->options_s, pkt + ((got_link == 1) ? LIBNET_ETH_H : 
                0))) == -1)
        {
            fprintf(stderr, "ERROR: Unable to add TCP options, discarding "
                    "them.\n");
        }
    }

    if (got_link)
        libnet_do_checksum(pkt + LIBNET_ETH_H, IPPROTO_IP, LIBNET_IP_H +
                ipod->options_s);

    libnet_do_checksum(pkt + ((got_link == 1) ? LIBNET_ETH_H : 0), 
            IPPROTO_TCP, LIBNET_TCP_H + pd->payload_s + tcpod->options_s);

    if (got_link)
        n = libnet_write_link_layer(l2, device, pkt, tcp_packetlen);
    else
        n = libnet_write_ip(sockfd, pkt, tcp_packetlen);

#ifdef DEBUG
    printf("DEBUG: tcp_packetlen is %u.\n", tcp_packetlen);
#endif
    if (verbose == 2)
        hexdump(pkt, tcp_packetlen);

    if (n != tcp_packetlen)
    {
        fprintf(stderr, "ERROR: Incomplete packet injection.  Only wrote "
                "%d bytes.\n", n);
    }
    else
    {
        if (verbose)
        {
            if (got_link)
                printf("Wrote %d byte TCP packet through linktype %s.\n", n, 
                        nemesis_lookup_linktype(l2->linktype));
            else
                printf("Wrote %d byte TCP packet.\n", n);
        }
    }
    libnet_destroy_packet(&pkt);
    if (got_link)
        libnet_close_link_interface(l2);
    else
        libnet_close_raw_sock(sockfd);
    return n;
}

Generated by  Doxygen 1.6.0   Back to index