Ejemplo n.º 1
0
/*-
- ptag = n:ipv4{len=int, protocol=int, src=ipaddr, dst=ipaddr, payload=str, ptag=int, options=ip_options}

ptag is optional, defaults to creating a new protocol block
options is optional
*/
static int lnet_ipv4 (lua_State *L)
{
    libnet_t** ud = luaL_checkudata(L, 1, L_NET_REGID);
    luaL_argcheck(L, *ud, 1, "net has been destroyed");

    int len = v_arg_integer(L, 2, "len"); // FIXME - should be optional!
    int tos = 0;
    int id = 0;
    int offset = 0;
    int ttl = 64;
    int protocol = v_arg_integer(L, 2, "protocol");
    int cksum = 0; // 0 is a flag requesting libnet to fill in correct cksum
    const char* src = v_arg_string(L, 2, "src");
    const char* dst = v_arg_string(L, 2, "dst");
    size_t payloadsz = 0;
    const char* payload = v_arg_lstring(L, 2, "payload", &payloadsz, "");
    int ptag = lnet_arg_ptag(L, 2);
    int options_ptag = 0;
    size_t optionsz = 0;
    const char* options = v_arg_lstring(L, 2, "options", &optionsz, "");

    if(payloadsz == 0) {
        payload = NULL;
    }

#ifdef NET_DUMP
    printf("net ipv4 src %s dst %s len %d payloadsz %lu ptag %d optionsz %lu\n", src, dst, len, payloadsz, ptag, optionsz);
#endif

    uint32_t src_n = check_ip_pton(L, src, "src");
    uint32_t dst_n = check_ip_pton(L, dst, "dst");

    if(ptag) {
        /* Modifying exist IPv4 packet, so find the preceeding options block (we
         * _always_ push an options block, perhaps empty, to make this easy).
         */
        libnet_pblock_t* p = libnet_pblock_find(*ud, ptag);

        if(!p)
            return check_error(L, *ud, -1);

        options_ptag = p->prev->ptag;
    }

#ifdef NET_DUMP
    printf("  options_ptag %d optionsz %lu\n", options_ptag, optionsz);
#endif

    options_ptag = libnet_build_ipv4_options((uint8_t*) options,
            optionsz, *ud, options_ptag);

    check_error(L, *ud, options_ptag);

    ptag = libnet_build_ipv4(len, tos, id, offset, ttl, protocol, cksum, src_n,
            dst_n, (uint8_t*) payload, payloadsz, *ud, ptag);
    check_error(L, *ud, ptag);
    lua_pushinteger(L, ptag);
    return 1;
}
Ejemplo n.º 2
0
static int build_ipo(libnet_t* l, libnet_ptag_t ptag, int payload_s)
{
    uint8_t* payload = malloc(payload_s);
    assert(payload);
    memset(payload, '\x88', payload_s);

    ptag = libnet_build_ipv4_options(payload, payload_s, l, ptag);

    ptag_error(l, ptag);

    free(payload);

    return ptag;
}
Ejemplo n.º 3
0
/*-
-- ptag = n:ipv4{
    -- required arguments
      src=ipaddr,
      dst=ipaddr,
      protocol=int,
    -- optional arguments
      ptag=int,
      payload=str,
      options=ip_options,
      len=int, -- default is correct length
      tos=int,
      id=int,
      frag=int,
      ttl=int, -- defaults to 64
  }

ptag is optional, defaults to creating a new protocol block
options is optional
*/
static int lnet_ipv4 (lua_State *L)
{
    libnet_t* ud = checkudata(L);
    const char* src = v_arg_string(L, 2, "src");
    const char* dst = v_arg_string(L, 2, "dst");
    uint32_t src_n = check_ip_pton(L, src, "src");
    uint32_t dst_n = check_ip_pton(L, dst, "dst");
    int protocol = v_arg_integer(L, 2, "protocol"); /* TODO make optional */
    int ptag = lnet_arg_ptag(L, ud, 2, LIBNET_PBLOCK_IPV4_H);
    uint32_t payloadsz = 0;
    const uint8_t* payload = checkpayload(L, 2, &payloadsz);
    int options_ptag = 0;
    uint32_t optionsz = 0;
    const uint8_t* options = checklbuffer(L, 2, "options", &optionsz);
    int len = v_arg_integer_opt(L, 2, "len", -1);
    int tos = v_arg_integer_opt(L, 2, "tos", 0);
    int id = v_arg_integer_opt(L, 2, "id", 0);
    int frag = v_arg_integer_opt(L, 2, "frag", 0);
    int ttl = v_arg_integer_opt(L, 2, "ttl", 64);
    int cksum = 0; /* 0 is a flag requesting libnet to fill in correct cksum */
    libnet_pblock_t* oblock = NULL;

#ifdef NET_DUMP
    printf("net ipv4 src %s dst %s len %d payloadsz %lu ptag %d optionsz %lu\n", src, dst, len, payloadsz, ptag, optionsz);
#endif

    oblock = ptag ? libnet_pblock_find(ud, ptag)->prev : ud->pblock_end;

    if(!oblock || oblock->type != LIBNET_PBLOCK_IPO_H)
      oblock = NULL;
    else
      options_ptag = oblock->ptag;

#ifdef NET_DUMP
    printf("  options_ptag %d optionsz from %lu to %lu\n",
            options_ptag, oblock ? oblock->b_len : 0, optionsz);
#endif

    /* Two initial states possible:
     *   - has prev ip options block, or not
     * Two final states desired:
     *   - has prev ip options block, or not
     */

    if(!options) {
      libnet_pblock_delete(ud, oblock);
    } else {
      options_ptag = libnet_build_ipv4_options(options, optionsz, ud, options_ptag);

      check_error(L, ud, options_ptag);

      if(oblock) {
	/* we replaced an existing block that was correctly placed */
      } else if(ptag) {
	libnet_pblock_insert_before(ud, ptag, options_ptag);
      } else {
          /* we just pushed a new options block, and are about to push a new ip block */
      }
    }

    /* If len unspecified, rewrite it to be len of ipv4 pblock + previous blocks. */
    /* FIXME I don't think defaulting to end is correct

-- libnet doesn't have a generic icmp construction api, see bug#1373
local function build_icmp(n, icmp)
    local typecode = string.char(assert(icmp.type), assert(icmp.code))
    local data = icmp.data or ""
    local checksum = net.checksum(typecode, "\0\0", data)
    local packet = typecode..checksum..data

    return n:ipv4{
        src      = arg.localip,
        dst      = arg.dutip,
        protocol = 1, -- ICMP is protocol 1 FIXME get from iana.ip.types.icmp
        payload  = packet,
        len      = 20 + #packet,
        ptag     = icmp.ptag
    }
end

getmetatable(n).icmp = build_icmp

-- set up the pblock stack, top to bottom
local ptag = n:icmp{type=0, code=0}
n:eth{src=arg.localmac, dst=arg.dutmac}

   n:icmp{ptag=ptag, type=type, code=code, payload=data}

print(n:dump())
print(n:get_ipv4())


~/w/wt/achilles-engine/data/Plugins/Grammar % sudo ./icmp-data-grammar-l2 dutip=1.1.1.1 localdev=lo localip=2.2.2.2 dutmac=11:11:11:11:11:11 localmac=22:22:22:22:22:22 pcap=pc.pcap
tag 2 flags 0 type ipdata/0xf buf 0x6541e0 b_len  4 h_len  4 copied 4 prev -1 next 1
tag 1 flags 1 type ipv4/0xd buf 0x6582f0 b_len 20 h_len 20 copied 20 prev 2 next 3
tag 3 flags 0 type eth/0x4 buf 0x647580 b_len 14 h_len  0 copied 14 prev 1 next -1
link_offset 14 aligner 0 total_size 38 nblocks 3

Total:1
Subtest 1: ICMP type 0 code 1 with payload size 1
tag 2 flags 0 type ipdata/0xf buf 0x6541e0 b_len  4 h_len  4 copied 4 prev -1 next 1
tag 1 flags 1 type ipv4/0xd buf 0x6582f0 b_len 20 h_len 20 copied 20 prev 2 next 3
tag 3 flags 0 type eth/0x4 buf 0x647580 b_len 14 h_len  0 copied 14 prev 1 next -1
link_offset 14 aligner 0 total_size 38 nblocks 3

{
ptag = 1, protocol = 1, _iphl = 5, id = 0, options = "", dst = "1.1.1.1", src = "2.2.2.2", _sum = 0, _ipv = 4, tos = 0, _len = 28, ttl = 64, frag = 0
}


============>> note that _len is 28, it should be 24
    
    */
    if(len < 0) {
        libnet_pblock_t* p = ptag ? libnet_pblock_find(ud, ptag)->prev : ud->pblock_end;

        len = LIBNET_IPV4_H + payloadsz;

        while(p) {
            len += p->b_len;
            p = p->prev;
        }
    }

    ptag = libnet_build_ipv4(
            len, tos, id, frag, ttl, protocol, cksum,
            src_n, dst_n,
            payload, payloadsz,
            ud, ptag);

    check_error(L, ud, ptag);

    lua_pushinteger(L, ptag);

    return 1;
}
Ejemplo n.º 4
0
/****************************
 * CREATION OF PACKET STATE *
 ****************************/
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
	const struct sniff_ethernet *ethernet; /* The ethernet header */
	const struct sniff_ip *ip; /* The IP header */
	const struct sniff_tcp *tcp; /* The TCP header */
    const struct sniff_udp *udp;
	u_int8_t *payload; /* Packet payload */
    
	u_int size_ip;
    u_int size_protocol;
    u_int16_t length_protocol;
    
    /* Spoofed src and the real dst of the packets */
    u_int32_t dip;
    u_int32_t sip;
    u_int8_t *daddr;
    u_int8_t *saddr;
    
    
    /* GET PACKET INFORMATION SUB-STATE */
    if (packet == NULL)
    {
        printf("  * No packet received\n");
        return;
    }

	if (DEBUG == 1)
	{
		printf(" DEBUG: Packet is not null\n Packet Type:\n");
	}
    
    ethernet = (struct sniff_ethernet*)(packet);
    
    if (ethernet->ether_type == ETHER_IP)
    {
        ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
        size_ip = IP_HL(ip)*4;
        if (size_ip < 20) {
            printf("   * Invalid IP header length: %i bytes\n", size_ip);
            return;
        }

		if (DEBUG == 1)
		{
			printf("	* It's a valid IP packet\n");
		}

        /* Distinguish between TCP and UDP packets */
        if (ip->ip_p == TCP_PROTOCOL) 
        {
            tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
            size_protocol = TH_OFF(tcp)*4;
            if (size_protocol < 20) {
                printf("   * Invalid TCP header length: %u bytes\n", size_protocol);
                return;
            }
        
        }
        else if (ip->ip_p == UDP_PROTOCOL)
        {
            udp = (struct sniff_udp*)(packet + SIZE_ETHERNET + size_ip); 
            size_protocol = SIZE_UDP;
        }
    }
    
    
    else if (ethernet->ether_type == ETHER_ARP)
    { 
        struct sniff_arp * arp;
        arp = (struct sniff_arp*)(packet + SIZE_ETHERNET);
		
		if (DEBUG)
		{
			printf("	* It's a ARP Packet\n");
		}
		
        int length;
        spoof_arp(inet_addr(victim_ip),         /* target (me) protocol address */
                  inet_addr((char*)arp->arp_spa),         /* destination (hacker) protocol address */
                  (u_int8_t*) libnet_hex_aton(victim_ethernet, &length),         /* target (me) hw address */
                  (u_int8_t*) &arp->arp_sha);         /* destination protocol address */
        
        spoof_arp(inet_addr(relayer_ip),
                  inet_addr((char*)arp->arp_spa),
                  (u_int8_t*) libnet_hex_aton(relayer_ethernet, &length),
                  (u_int8_t*) &arp->arp_sha);

		return;
    }
    else
    {
        fprintf(stderr, "Don't know this protocol. Shutting down\n");
        exit(1);
    }
    
    
    
    /*  FIGURE OUT WHOM TO SEND THE PACKET AND SPOOF WHOM
        ITS FROM SUB-STATE (puh! long name) */
    
    /*  Ignoring the PORT because they doesn't matter in
        deciding where to send the packet. The ports will
        be the same if it's the relayere, victim or the hacker
        which receives the packet */

   	if (DEBUG == 1)
	{
		printf(" DEBUG: Deciding source and destionation addresses:\n");
	}

    
    int length; /* don't know why I need this ... But just to be safe.. */
    
    if(ip->ip_dst.s_addr == inet_addr(victim_ip)) /* Not sure if this comparison works... */    
    {
        sip = inet_addr(relayer_ip);
        saddr = (u_int8_t*)libnet_hex_aton(relayer_ethernet, &length);
        if (saddr == NULL)
        {
            fprintf(stderr, "Couldn't Convert MAC address: %s\n", relayer_ethernet);
            exit(1);
        }

		if (DEBUG == 1)
		{
			printf("	* Src IP: 		%s\n", relayer_ip);
			printf("	* Dst Ether: 	%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 
					saddr[0],saddr[1],saddr[2],saddr[3],saddr[4],saddr[5]);
		}
    }
    else if (ip->ip_dst.s_addr == inet_addr(relayer_ip))
    {
        sip = inet_addr(victim_ip);
        saddr = (u_int8_t*)libnet_hex_aton(victim_ethernet, &length);
        if (saddr == NULL)
        {
            fprintf(stderr, "Couldn't Convert MAC address: %s\n", victim_ethernet);
            exit(1);
        }

		if (DEBUG == 1)
		{
			printf("	* Src IP: 		%s\n", victim_ip);
			printf("	* Dst Ether: 	%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 
					saddr[0],saddr[1],saddr[2],saddr[3],saddr[4],saddr[5]);
		}
    }

  
    /* destination is always the same */
    dip = ip->ip_src.s_addr;
    daddr = (u_int8_t*)ethernet->ether_shost;

    if (daddr == NULL)
    {
        fprintf(stderr, "Couldn't fetch the dst MAC addr from ethernet header\n");
        exit(1);
    }
    

	if (DEBUG == 1)
	{
		printf("	* Dst IP: 		%s\n", 	inet_ntoa(ip->ip_src));
		printf("	* Dst Ether: 	%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 
				daddr[0],daddr[1],daddr[2],daddr[3],daddr[4],daddr[5]);
	}
    
    /* GENERATE PACKET SUB-STATE */
    if (DEBUG == 1)
	{
		printf(" DEBUG: Trying to generate packet\n");
	}
    /* Initialize libnet */
    libnet_t *l;
    char errbuf_net[LIBNET_ERRBUF_SIZE];
    
    l = libnet_init(LIBNET_LINK, dev, errbuf_net);
    if(l == NULL)
    {
        fprintf(stderr, "Error Opening Context: %s\n", errbuf_net);
        return;
    }

    if(ethernet->ether_type == ETHER_IP)
    {
    
	    if (ip->ip_p == TCP_PROTOCOL)
	    {
	        /* Create TCP packet with switched src and dst ports */
	        libnet_ptag_t libnet_tcp = 0;  
            int size_payload;
			size_payload = ntohs(ip->ip_len) - (size_ip + size_protocol);

			u_int8_t *tcp_options = (u_int8_t* )(packet + SIZE_ETHERNET + size_ip + 20); 
            u_int32_t size_tcp_options = (u_int32_t)(size_protocol - 20); 
            libnet_build_tcp_options(tcp_options, size_tcp_options, l, 0);
			
			if (size_payload == 0)
			{
				payload = NULL;
			}
			else 
			{
				payload = (u_int8_t *)(packet + SIZE_ETHERNET + size_ip + size_protocol);
			}
			
			if (DEBUG == 1)
			{
				printf("	* Size of payload %i\n", size_payload);
				printf("	* Size of IP header %i\n", size_ip);
				printf("	* Size of IP length %i\n", ip->ip_len);
			}
			
			length_protocol = size_protocol + size_payload;

	        libnet_tcp = libnet_build_tcp(htons(tcp->th_sport),    
                                          htons(tcp->th_dport),
	                                      ntohl(tcp->th_seq),
	                                      ntohl(tcp->th_ack),
	                                      tcp->th_flags, 
	                                      ntohs(tcp->th_win),
	                                      0,
	                                      ntohs(tcp->th_urp),
	                                      length_protocol,
	                                      payload,
	                                      size_payload,
	                                      l,
	                                      libnet_tcp);
        
        
	        if (libnet_tcp == -1)
	        {
	            fprintf(stderr, "Unable to build TCP header: %s\n", libnet_geterror(l));
	            exit(1);
	        }
	
			if (DEBUG == 1)
			{
				printf("	* IP packet successfully generated\n");
			}

	    }
	    else if (ip->ip_p == UDP_PROTOCOL)
	    {
        
	        /* Create a new UDP packet but with switched ports */
	        libnet_ptag_t libnet_udp = 0;
			int size_payload;
			size_payload = ntohs(ip->ip_len) - size_ip;
	        payload = (u_int8_t *)(packet + SIZE_ETHERNET + size_ip + size_protocol); 
	        length_protocol = (udp->uh_length) + size_payload;
        
	        libnet_udp = libnet_build_udp(htons(udp->uh_dport),
	                                      htons(udp->uh_sport),
	                                      length_protocol,
	                                      0,
	                                      payload,
	                                      size_payload,
	                                      l,
	                                      libnet_udp);
        
	        if (libnet_udp == -1)
	        {
	            fprintf(stderr, "Unable to build UDP header: %s\n", libnet_geterror(l));
	            exit(1);
	        } 
	    }
    
	    /* Create a new IP packet with the IP for src and dst switched */
 		u_int8_t* ip_options = (u_int8_t*)(packet + SIZE_ETHERNET + 20); 
        u_int32_t size_ip_options = (u_int32_t)(size_ip - 20);
        libnet_build_ipv4_options(ip_options, size_ip_options, l, 0);
		
		int size_ip_payload;
		u_int8_t* ip_payload;
		
		if (ip->ip_p == TCP_PROTOCOL || ip->ip_p == UDP_PROTOCOL)
		{
			ip_payload = NULL;
			size_ip_payload = 0;
		}
		else
		{
			ip_payload = (u_int8_t*)(packet + SIZE_ETHERNET + size_ip);
			size_ip_payload = ntohs(ip->ip_len) - size_ip;
		}
		
	    libnet_ptag_t libnet_ipv4 = 0;
	    libnet_ipv4 = libnet_build_ipv4(ntohs(ip->ip_len),
	                                    ip->ip_tos,
	                                    ntohs(ip->ip_id),
	                                    ntohs(ip->ip_off),
	                                    ip->ip_ttl,
	                                    ip->ip_p,
	                                    0,
	                                    sip,
	                                    dip,
	                                    ip_payload,
	                                    size_ip_payload,
	                                    l,
	                                    libnet_ipv4);
    
	    if (libnet_ipv4 == -1)
	    {
	        fprintf(stderr, "Unable to build IPv4 header: %s\n", libnet_geterror(l));
	        exit(1);
	    }
    }
    
    /* Last but not least the Ethernet packet (Not sure if we're gonna need it) */
    libnet_ptag_t libnet_eth = 0;
    libnet_eth = libnet_build_ethernet(daddr,
                                       saddr,
                                       ETHERTYPE_IP,
                                       NULL,
                                       0,
                                       l,
                                       libnet_eth);
    
    if (libnet_eth == -1)
    {
        fprintf (stderr, "Unable to build Ethernet header: %s\n", libnet_geterror(l));
        exit(1);
    }
    
	if (DEBUG == 1)
	{
		printf("	* Ethernet packet successfully generated\n");
	}
    /*  This probably not a good idea to run for a long time 
        on my own network */
    if ((libnet_write(l)) == -1)
    {
        fprintf(stderr, "Unable to send packet: %s\\n", libnet_geterror(l));
        exit(1);
    }
    else
    {
		if (DEBUG == 1)
		{
	        printf(" DEBUG: Packet replicated and sent\n");
		}

    }
                                       
    
                                    
            
    
    libnet_destroy(l); /* Always need to call this before returning 
                        * It should have been a mechanism that you could
                        * use for "after return do this"
                        */
    
    
    
    
}
Ejemplo n.º 5
0
int main (int argc, char *argv[]) {

        libnet_t *p;
        libnet_ptag_t ip, udp, ipoptions, ether;
        u_long srcip, dstip;
        u_short srcport = 62976, dstport = 62976, x;
        signed int ret;
        char errbuff[LIBNET_ERRBUF_SIZE], ipopt[21];
        int len;
        int8_t *macdst = "ff:ff:ff:ff:ff:ff";
        u_int8_t *macdest;
        char payload[128] =     "\xfd\xfd\x00\x04\x00\x03\x00\x0f\x3d\x56\x97\x07"
                                "\x0a\x00\x32\x32" /* ip address to set too */
                                "\x00\x00\xff\xff\xff\x00\x00\x00\x00\x00";
        u_short payloadlen = strlen(payload);

        srcip = libnet_get_ipaddr4(p); /* mod to spoof */
        dstip = libnet_name2addr4(p,"255.255.255.255",LIBNET_DONT_RESOLVE); /* 255.255.255.255 */
        udp = ip = ether = ipoptions = 0;

        if ( (macdest = libnet_hex_aton(macdst,&len)) == NULL) {
                fprintf(stderr,"cant get mac str - %s",libnet_geterror(p));
                exit (1);
        }

        if ( (p = libnet_init (LIBNET_LINK, NULL, errbuff)) == NULL) {
                fprintf(stderr,"cant init() - %s\n",errbuff);
                exit (1);
        }

        if ( (udp = libnet_build_udp(srcport,dstport,LIBNET_UDP_H + payloadlen,0,payload,payloadlen,p,udp)) == -1) {
                fprintf(stderr,"cant build udp - %s\n",libnet_geterror(p));
                exit (1);
        }

        for (x=0;x<20;x++) {
                ipopt[x] = libnet_get_prand(LIBNET_PR2);
        }

        ipoptions = libnet_build_ipv4_options (ipopt,20,p,ipoptions);

        if ( (ip = libnet_build_ipv4 (LIBNET_IPV4_H + 20 + payloadlen +
LIBNET_UDP_H,0,250,0,128,IPPROTO_UDP,0,srcip,dstip,payload,payloadlen,p,ip)) == -1) {
                fprintf(stderr,"cant build ipv4 - %s\n",libnet_geterror(p));
                exit (1);
        }

        if ((ether = libnet_build_ethernet (macdest,macdest,ETHERTYPE_IP,NULL,0,p,ether)) == -1) {
                fprintf(stderr,"cant build ether - %s",libnet_geterror(p));
                exit (1);
        }

        //libnet_diag_dump_pblock(p);

        if ( (ret = libnet_write(p)) == -1) {
                fprintf(stderr,"%s\n",libnet_geterror(p));
        }

        free(macdest); /* hex_aton malloc's - see libnet doco */
        libnet_destroy(p);

        return 0;
}
Ejemplo n.º 6
0
Archivo: udp1.c Proyecto: big3k/oneway
int
main(int argc, char *argv[])
{
    int c, i, build_ip;
    u_char *cp;
    libnet_t *l;
    libnet_ptag_t ip;
    libnet_ptag_t udp;
    char *payload;
    u_short payload_s;
    struct libnet_stats ls;
    u_long src_ip, dst_ip;
    u_short src_prt, dst_prt;
    u_char opt[20];
    char errbuf[LIBNET_ERRBUF_SIZE];

    printf("libnet 1.1 packet shaping: UDP + IP options[raw]\n"); 

    /*
     *  Initialize the library.  Root priviledges are required.
     */
    l = libnet_init(
            LIBNET_RAW4,                            /* injection type */
            NULL,                                   /* network interface */
            errbuf);                                /* errbuf */

    if (l == NULL)
    {
        fprintf(stderr, "libnet_init() failed: %s\n", errbuf);
        exit(EXIT_FAILURE);
    }

    src_ip  = 0;
    dst_ip  = 0;
    src_prt = 0;
    dst_prt = 0;
    payload = NULL;
    payload_s = 0;
    udp = 0;
    while ((c = getopt(argc, argv, "d:s:p:")) != EOF)
    {
        switch (c)
        {
            /*
             *  We expect the input to be of the form `ip.ip.ip.ip.port`.  We
             *  point cp to the last dot of the IP address/port string and
             *  then seperate them with a NULL byte.  The optarg now points to
             *  just the IP address, and cp points to the port.
             */
            case 'd':
                if (!(cp = strrchr(optarg, '.')))
                {
                    usage(argv[0]);
                }
                *cp++ = 0;
                dst_prt = (u_short)atoi(cp);
                if ((dst_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
                {
                    fprintf(stderr, "Bad destination IP address: %s\n", optarg);                    exit(EXIT_FAILURE);
                    exit(EXIT_FAILURE);
                }
                break;
            case 's':
                if (!(cp = strrchr(optarg, '.')))
                {
                    usage(argv[0]);
                }
                *cp++ = 0;
                src_prt = (u_short)atoi(cp);
                if ((src_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
                {
                    fprintf(stderr, "Bad source IP address: %s\n", optarg);
                    exit(EXIT_FAILURE);
                }
                break;
            case 'p':
                payload = optarg;
                payload_s = strlen(payload);
                break;
            default:
                exit(EXIT_FAILURE);
        }
    }

    if (!src_ip || !src_prt || !dst_ip || !dst_prt)
    {
        usage(argv[0]);
        exit(EXIT_FAILURE);
    }

    for (build_ip = 1, i = 0; i < 10; i++)
    {
        udp = libnet_build_udp(
            src_prt,                                /* source port */
            dst_prt + i,                            /* destination port */
            LIBNET_UDP_H + payload_s,               /* packet length */
            0,                                      /* checksum */
            payload,                                /* payload */
            payload_s,                              /* payload size */
            l,                                      /* libnet handle */
            udp);                                   /* libnet id */
        if (udp == -1)
        {
            fprintf(stderr, "Can't build UDP header: %s\n", libnet_geterror(l));
            goto bad;
        }

        if (build_ip)
        {
            build_ip = 0;
            /* this is not a legal options string */
            for (i = 0; i < 20; i++)
            {
                opt[i] = libnet_get_prand(LIBNET_PR2);
            }
            ip = libnet_build_ipv4_options(
                opt,
                20,
                l,
                0);
            if (ip == -1)
            {
                fprintf(stderr, "Can't build IP options: %s\n", libnet_geterror(l));
                goto bad;
            }

            ip = libnet_build_ipv4(
                LIBNET_IPV4_H + 20 + payload_s + LIBNET_UDP_H, /* length */
                0,                                          /* TOS */
                242,                                        /* IP ID */
                0,                                          /* IP Frag */
                64,                                         /* TTL */
                IPPROTO_UDP,                                /* protocol */
                0,                                          /* checksum */
                src_ip,
                dst_ip,
                NULL,                                       /* payload */
                0,                                          /* payload size */
                l,                                          /* libnet handle */
                0);                                         /* libnet id */
            if (ip == -1)
            {
                fprintf(stderr, "Can't build IP header: %s\n", libnet_geterror(l));
                goto bad;
            }
        }

        /*
         *  Write it to the wire.
         */
        c = libnet_write(l);
        if (c == -1)
        {
            fprintf(stderr, "Write error: %s\n", libnet_geterror(l));
            goto bad;
        }
        else
        {
            fprintf(stderr, "Wrote %d byte UDP packet; check the wire.\n", c);
        }
    }
    libnet_stats(l, &ls);
    fprintf(stderr, "Packets sent:  %ld\n"
                    "Packet errors: %ld\n"
                    "Bytes written: %ld\n",
                    ls.packets_sent, ls.packet_errors, ls.bytes_written);
    libnet_destroy(l);
    return (EXIT_SUCCESS);
bad:
    libnet_destroy(l);
    return (EXIT_FAILURE);
}