197903da2202008733f50e69997029d7a5cfffcb8mreed/******************************************************************************/ 297903da2202008733f50e69997029d7a5cfffcb8mreed/* */ 397903da2202008733f50e69997029d7a5cfffcb8mreed/* Copyright (c) International Business Machines Corp., 2006 */ 497903da2202008733f50e69997029d7a5cfffcb8mreed/* */ 597903da2202008733f50e69997029d7a5cfffcb8mreed/* This program is free software; you can redistribute it and/or modify */ 697903da2202008733f50e69997029d7a5cfffcb8mreed/* it under the terms of the GNU General Public License as published by */ 797903da2202008733f50e69997029d7a5cfffcb8mreed/* the Free Software Foundation; either version 2 of the License, or */ 897903da2202008733f50e69997029d7a5cfffcb8mreed/* (at your option) any later version. */ 997903da2202008733f50e69997029d7a5cfffcb8mreed/* */ 1097903da2202008733f50e69997029d7a5cfffcb8mreed/* This program is distributed in the hope that it will be useful, */ 1197903da2202008733f50e69997029d7a5cfffcb8mreed/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 1297903da2202008733f50e69997029d7a5cfffcb8mreed/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 1397903da2202008733f50e69997029d7a5cfffcb8mreed/* the GNU General Public License for more details. */ 1497903da2202008733f50e69997029d7a5cfffcb8mreed/* */ 1597903da2202008733f50e69997029d7a5cfffcb8mreed/* You should have received a copy of the GNU General Public License */ 1697903da2202008733f50e69997029d7a5cfffcb8mreed/* along with this program; if not, write to the Free Software */ 174548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 1897903da2202008733f50e69997029d7a5cfffcb8mreed/* */ 1997903da2202008733f50e69997029d7a5cfffcb8mreed/******************************************************************************/ 2097903da2202008733f50e69997029d7a5cfffcb8mreed 2197903da2202008733f50e69997029d7a5cfffcb8mreed/* 2297903da2202008733f50e69997029d7a5cfffcb8mreed * File: 2397903da2202008733f50e69997029d7a5cfffcb8mreed * ns-icmpv4_sender.c 2497903da2202008733f50e69997029d7a5cfffcb8mreed * 2597903da2202008733f50e69997029d7a5cfffcb8mreed * Description: 2697903da2202008733f50e69997029d7a5cfffcb8mreed * This is ICMPv4 echo request sender. 2797903da2202008733f50e69997029d7a5cfffcb8mreed * This utility is also able to set illegal information in the IP header 2897903da2202008733f50e69997029d7a5cfffcb8mreed * 2997903da2202008733f50e69997029d7a5cfffcb8mreed * Author: 3097903da2202008733f50e69997029d7a5cfffcb8mreed * Mitsuru Chinen <mitch@jp.ibm.com> 3197903da2202008733f50e69997029d7a5cfffcb8mreed * 3297903da2202008733f50e69997029d7a5cfffcb8mreed * History: 3397903da2202008733f50e69997029d7a5cfffcb8mreed * Mar 5 2006 - Created (Mitsuru Chinen) 3497903da2202008733f50e69997029d7a5cfffcb8mreed *---------------------------------------------------------------------------*/ 3597903da2202008733f50e69997029d7a5cfffcb8mreed 3697903da2202008733f50e69997029d7a5cfffcb8mreed/* 3797903da2202008733f50e69997029d7a5cfffcb8mreed * Header Files 3897903da2202008733f50e69997029d7a5cfffcb8mreed */ 3997903da2202008733f50e69997029d7a5cfffcb8mreed#include <stdio.h> 4097903da2202008733f50e69997029d7a5cfffcb8mreed#include <stdlib.h> 4197903da2202008733f50e69997029d7a5cfffcb8mreed#include <string.h> 4297903da2202008733f50e69997029d7a5cfffcb8mreed#include <errno.h> 4397903da2202008733f50e69997029d7a5cfffcb8mreed#include <netdb.h> 4497903da2202008733f50e69997029d7a5cfffcb8mreed#include <signal.h> 4597903da2202008733f50e69997029d7a5cfffcb8mreed#include <time.h> 4697903da2202008733f50e69997029d7a5cfffcb8mreed#include <unistd.h> 4797903da2202008733f50e69997029d7a5cfffcb8mreed#include <sys/ioctl.h> 4897903da2202008733f50e69997029d7a5cfffcb8mreed#include <sys/socket.h> 4997903da2202008733f50e69997029d7a5cfffcb8mreed#include <arpa/inet.h> 5097903da2202008733f50e69997029d7a5cfffcb8mreed#include <net/ethernet.h> 5197903da2202008733f50e69997029d7a5cfffcb8mreed#include <net/if_arp.h> 5297903da2202008733f50e69997029d7a5cfffcb8mreed 5397903da2202008733f50e69997029d7a5cfffcb8mreed#include "ns-traffic.h" 5497903da2202008733f50e69997029d7a5cfffcb8mreed 5597903da2202008733f50e69997029d7a5cfffcb8mreed/* 5697903da2202008733f50e69997029d7a5cfffcb8mreed * Structure Definitions 5797903da2202008733f50e69997029d7a5cfffcb8mreed */ 5897903da2202008733f50e69997029d7a5cfffcb8mreedstruct icmpv4_fake { 59354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct ip4_datagram pkt; 60354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *src_ifname; 61354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct sockaddr_ll saddr_ll; 62354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct sockaddr_ll daddr_ll; 63354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct in_addr saddr; 64354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct in_addr daddr; 65354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned short int pkt_size; 66354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned short int data_size; 67354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao double timeout; 68354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 69354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao u_int16_t fake_flag; 7097903da2202008733f50e69997029d7a5cfffcb8mreed}; 7197903da2202008733f50e69997029d7a5cfffcb8mreed 7297903da2202008733f50e69997029d7a5cfffcb8mreed/* 7397903da2202008733f50e69997029d7a5cfffcb8mreed * Gloval variables 7497903da2202008733f50e69997029d7a5cfffcb8mreed */ 7597903da2202008733f50e69997029d7a5cfffcb8mreedchar *program_name; /* program name */ 7697903da2202008733f50e69997029d7a5cfffcb8mreedstruct sigaction handler; /* Behavior for a signal */ 7797903da2202008733f50e69997029d7a5cfffcb8mreedint catch_sighup; /* When catch the SIGHUP, set to non-zero */ 7897903da2202008733f50e69997029d7a5cfffcb8mreed 7997903da2202008733f50e69997029d7a5cfffcb8mreed/* 8097903da2202008733f50e69997029d7a5cfffcb8mreed * Function: usage() 8197903da2202008733f50e69997029d7a5cfffcb8mreed * 8297903da2202008733f50e69997029d7a5cfffcb8mreed * Descripton: 8397903da2202008733f50e69997029d7a5cfffcb8mreed * Print the usage of this program. Then, terminate this program with 8497903da2202008733f50e69997029d7a5cfffcb8mreed * the specified exit value. 8597903da2202008733f50e69997029d7a5cfffcb8mreed * 8697903da2202008733f50e69997029d7a5cfffcb8mreed * Argument: 8797903da2202008733f50e69997029d7a5cfffcb8mreed * exit_value: exit value 8897903da2202008733f50e69997029d7a5cfffcb8mreed * 8997903da2202008733f50e69997029d7a5cfffcb8mreed * Return value: 9097903da2202008733f50e69997029d7a5cfffcb8mreed * This function does not return. 9197903da2202008733f50e69997029d7a5cfffcb8mreed */ 92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid usage(char *program_name, int exit_value) 9397903da2202008733f50e69997029d7a5cfffcb8mreed{ 94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao FILE *stream = stdout; /* stream where the usage is output */ 95354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (exit_value == EXIT_FAILURE) 97354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao stream = stderr; 98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stream, "%s [OPTION]\n" 100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t-I if_name\tInterface name of the source host\n" 101354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t-S ip_addr\tIPv4 address of the source host\n" 102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t-M mac_addr\tMAC address of the destination host\n" 103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t-D ip_addr\tIPv4 address of the destination host\n" 104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t-s packetsize\tnumber of data bytes (exclude header)\n" 105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t-t value\ttimeout [sec]\n" 106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t-d\t\tdisplay debug informations\n" 107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t-h\t\tdisplay this usage\n" 108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\n" 109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t[options for fake]\n" 110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t -c\tbreak checksum\n" 111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t -f\tbreak fragment information\n" 112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t -i\tbreak IPv4 destination address\n" 113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t -l\tbreak header length\n" 114354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t -L\tbreak total length\n" 115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t -p\tbreak protocol number\n" 116354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\t -v\tbreak IP version\n", program_name); 117354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(exit_value); 11897903da2202008733f50e69997029d7a5cfffcb8mreed} 11997903da2202008733f50e69997029d7a5cfffcb8mreed 12097903da2202008733f50e69997029d7a5cfffcb8mreed/* 12197903da2202008733f50e69997029d7a5cfffcb8mreed * Function: set_signal_flag() 12297903da2202008733f50e69997029d7a5cfffcb8mreed * 12397903da2202008733f50e69997029d7a5cfffcb8mreed * Description: 12497903da2202008733f50e69997029d7a5cfffcb8mreed * This function sets global variables accordig to signal 12597903da2202008733f50e69997029d7a5cfffcb8mreed * 12697903da2202008733f50e69997029d7a5cfffcb8mreed * Argument: 12797903da2202008733f50e69997029d7a5cfffcb8mreed * type: type of signal 12897903da2202008733f50e69997029d7a5cfffcb8mreed * 12997903da2202008733f50e69997029d7a5cfffcb8mreed * Return value: 13097903da2202008733f50e69997029d7a5cfffcb8mreed * None 13197903da2202008733f50e69997029d7a5cfffcb8mreed */ 132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid set_signal_flag(int type) 13397903da2202008733f50e69997029d7a5cfffcb8mreed{ 134354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (debug) 135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Catch signal. type is %d\n", type); 13697903da2202008733f50e69997029d7a5cfffcb8mreed 137354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao switch (type) { 13897903da2202008733f50e69997029d7a5cfffcb8mreed case SIGHUP: 139354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao catch_sighup = 1; 140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao handler.sa_handler = SIG_IGN; 141354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (sigaction(type, &handler, NULL) < 0) 142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fatal_error("sigaction()"); 143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 14497903da2202008733f50e69997029d7a5cfffcb8mreed 14597903da2202008733f50e69997029d7a5cfffcb8mreed default: 146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Unexpected signal (%d) is caught\n", type); 147354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(EXIT_FAILURE); 148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 14997903da2202008733f50e69997029d7a5cfffcb8mreed} 15097903da2202008733f50e69997029d7a5cfffcb8mreed 15197903da2202008733f50e69997029d7a5cfffcb8mreed/* 15297903da2202008733f50e69997029d7a5cfffcb8mreed * Function: parse_options() 15397903da2202008733f50e69997029d7a5cfffcb8mreed * 15497903da2202008733f50e69997029d7a5cfffcb8mreed * Description: 15597903da2202008733f50e69997029d7a5cfffcb8mreed * This function parse the options, then modify the fake icmp data 15697903da2202008733f50e69997029d7a5cfffcb8mreed * 15797903da2202008733f50e69997029d7a5cfffcb8mreed * Argument: 15897903da2202008733f50e69997029d7a5cfffcb8mreed * argc: the number of argument 15997903da2202008733f50e69997029d7a5cfffcb8mreed * argv: arguments 16097903da2202008733f50e69997029d7a5cfffcb8mreed * fake_p: pointer to data of fake icmp data to modify 16197903da2202008733f50e69997029d7a5cfffcb8mreed * 16297903da2202008733f50e69997029d7a5cfffcb8mreed * Return value: 16397903da2202008733f50e69997029d7a5cfffcb8mreed * None 16497903da2202008733f50e69997029d7a5cfffcb8mreed */ 165354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid parse_options(int argc, char *argv[], struct icmpv4_fake *fake_p) 16697903da2202008733f50e69997029d7a5cfffcb8mreed{ 167354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int optc; /* option */ 168354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long opt_ul; /* option value in unsigned long */ 169354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao double opt_d; /* option value in double */ 170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct in_addr opt_addr; /* option value in struct in_addr */ 171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct sockaddr_ll opt_addr_ll; /* option value in struct sockaddr_ll */ 172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int is_specified_src_ifname = 0; 173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int is_specified_saddr = 0; 174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int is_specified_daddr_ll = 0; 175354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int is_specified_daddr = 0; 176354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 177354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao while ((optc = getopt(argc, argv, "I:S:M:D:s:t:dhcfilLpv")) != EOF) { 178354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao switch (optc) { 179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'I': 180354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->src_ifname = strdup(optarg); 181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_p->src_ifname == NULL) 182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fatal_error("strdup() failed."); 183354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao is_specified_src_ifname = 1; 184354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 186354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'S': 187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (inet_pton(AF_INET, optarg, &opt_addr) <= 0) { 188354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Source address is wrong\n"); 189354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_FAILURE); 190354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->saddr = opt_addr; 192354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao is_specified_saddr = 1; 193354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 194354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 195354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'M': 196354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (eth_pton(AF_INET, optarg, &opt_addr_ll)) { 197354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 198354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Destination MAC address is wrong\n"); 199354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_FAILURE); 200354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->daddr_ll = opt_addr_ll; 202354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao is_specified_daddr_ll = 1; 203354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 204354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 205354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'D': 206354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (inet_pton(AF_INET, optarg, &opt_addr) <= 0) { 207354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 208354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Destination address is wrong\n"); 209354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_FAILURE); 210354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 211354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->daddr = opt_addr; 212354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao is_specified_daddr = 1; 213354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 214354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 215354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 's': 216354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao opt_ul = strtoul(optarg, NULL, 0); 217354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (opt_ul > ICMPV4_DATA_MAXSIZE) { 218354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 219354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Data size sholud be less than %d\n", 220354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ICMPV4_DATA_MAXSIZE + 1); 221354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_FAILURE); 222354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 223354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->data_size = opt_ul; 224354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 225354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 226354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 't': 227354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao opt_d = strtod(optarg, NULL); 228354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (opt_d < 0.0) { 229354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 230354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Timeout should be positive value\n"); 231354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_FAILURE); 232354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 233354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->timeout = opt_d; 234354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 23597903da2202008733f50e69997029d7a5cfffcb8mreed 236354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'd': 237354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao debug = 1; 238354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 23997903da2202008733f50e69997029d7a5cfffcb8mreed 240354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'h': 241354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_SUCCESS); 242354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 24397903da2202008733f50e69997029d7a5cfffcb8mreed 244354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Options for fake */ 245354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'c': 246354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->fake_flag |= FAKE_CHECK; 247354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 24897903da2202008733f50e69997029d7a5cfffcb8mreed 249354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'f': 250354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->fake_flag |= FAKE_FRAGMENT; 251354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 25297903da2202008733f50e69997029d7a5cfffcb8mreed 253354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'i': 254354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->fake_flag |= FAKE_DADDR; 255354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 25697903da2202008733f50e69997029d7a5cfffcb8mreed 257354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'l': 258354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->fake_flag |= FAKE_IHL; 259354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 26097903da2202008733f50e69997029d7a5cfffcb8mreed 261354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'L': 262354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->fake_flag |= FAKE_TOT_LEN; 263354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 26497903da2202008733f50e69997029d7a5cfffcb8mreed 265354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'p': 266354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->fake_flag |= FAKE_PROTOCOL; 267354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 26897903da2202008733f50e69997029d7a5cfffcb8mreed 269354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'v': 270354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->fake_flag |= FAKE_VERSION; 271354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 27297903da2202008733f50e69997029d7a5cfffcb8mreed 273354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao default: 274354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_FAILURE); 275354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 276354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 27797903da2202008733f50e69997029d7a5cfffcb8mreed 278354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!is_specified_src_ifname) { 279354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 280354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Interface name of the source host is not specified\n"); 281354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_FAILURE); 282354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 28397903da2202008733f50e69997029d7a5cfffcb8mreed 284354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!is_specified_saddr) { 285354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Source IP address is not specified\n"); 286354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_FAILURE); 287354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 28897903da2202008733f50e69997029d7a5cfffcb8mreed 289354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!is_specified_daddr_ll) { 290354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Destination MAC address is not specified\n"); 291354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao usage(program_name, EXIT_FAILURE); 292354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 29397903da2202008733f50e69997029d7a5cfffcb8mreed 294354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!is_specified_daddr) { 295354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Destination IP address is not specified\n"); 29697903da2202008733f50e69997029d7a5cfffcb8mreed usage(program_name, EXIT_FAILURE); 29797903da2202008733f50e69997029d7a5cfffcb8mreed } 29897903da2202008733f50e69997029d7a5cfffcb8mreed} 29997903da2202008733f50e69997029d7a5cfffcb8mreed 30097903da2202008733f50e69997029d7a5cfffcb8mreed/* 30197903da2202008733f50e69997029d7a5cfffcb8mreed * Function: complete_eth_addrs() 30297903da2202008733f50e69997029d7a5cfffcb8mreed * 30397903da2202008733f50e69997029d7a5cfffcb8mreed * Description: 30497903da2202008733f50e69997029d7a5cfffcb8mreed * This function sets the source and destination ethernet address completely 30597903da2202008733f50e69997029d7a5cfffcb8mreed * 30697903da2202008733f50e69997029d7a5cfffcb8mreed * Argument: 30797903da2202008733f50e69997029d7a5cfffcb8mreed * fake_p: pointer to data of fake icmp structure 30897903da2202008733f50e69997029d7a5cfffcb8mreed * 30997903da2202008733f50e69997029d7a5cfffcb8mreed * Return value: 31097903da2202008733f50e69997029d7a5cfffcb8mreed * None 31197903da2202008733f50e69997029d7a5cfffcb8mreed * 31297903da2202008733f50e69997029d7a5cfffcb8mreed */ 313354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid complete_eth_addrs(struct icmpv4_fake *fake_p) 31497903da2202008733f50e69997029d7a5cfffcb8mreed{ 315354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int sock_fd; /* Socket for ioctl() */ 316354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct ifreq ifinfo; /* Interface information */ 31797903da2202008733f50e69997029d7a5cfffcb8mreed 318354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((sock_fd = socket(AF_PACKET, SOCK_DGRAM, 0)) < 0) 319354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fatal_error("socket()"); 32097903da2202008733f50e69997029d7a5cfffcb8mreed 321354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Source */ 322354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->saddr_ll.sll_family = AF_PACKET; /* Always AF_PACKET */ 323354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->saddr_ll.sll_protocol = htons(ETH_P_IP); /* IPv4 */ 324354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->saddr_ll.sll_hatype = ARPHRD_ETHER; /* Header type */ 325354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->saddr_ll.sll_pkttype = PACKET_HOST; /* Packet type */ 326354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->saddr_ll.sll_halen = ETH_ALEN; /* Length of address */ 32797903da2202008733f50e69997029d7a5cfffcb8mreed 328354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Get the MAC address of the interface at source host */ 329354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao get_ifinfo(&ifinfo, sock_fd, fake_p->src_ifname, SIOCGIFHWADDR); 330354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao memcpy(fake_p->saddr_ll.sll_addr, ifinfo.ifr_hwaddr.sa_data, ETH_ALEN); 33197903da2202008733f50e69997029d7a5cfffcb8mreed 332354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Get the interface index */ 333354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao get_ifinfo(&ifinfo, sock_fd, fake_p->src_ifname, SIOCGIFINDEX); 334354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->saddr_ll.sll_ifindex = ifinfo.ifr_ifindex; 335354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->daddr_ll.sll_ifindex = ifinfo.ifr_ifindex; 33697903da2202008733f50e69997029d7a5cfffcb8mreed 337354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(sock_fd); 33897903da2202008733f50e69997029d7a5cfffcb8mreed} 33997903da2202008733f50e69997029d7a5cfffcb8mreed 34097903da2202008733f50e69997029d7a5cfffcb8mreed/* 34197903da2202008733f50e69997029d7a5cfffcb8mreed * Function: create_clean_packet() 34297903da2202008733f50e69997029d7a5cfffcb8mreed * 34397903da2202008733f50e69997029d7a5cfffcb8mreed * Description: 34497903da2202008733f50e69997029d7a5cfffcb8mreed * This function creates icmpv4 packet without any fakes 34597903da2202008733f50e69997029d7a5cfffcb8mreed * 34697903da2202008733f50e69997029d7a5cfffcb8mreed * Argument: 34797903da2202008733f50e69997029d7a5cfffcb8mreed * fake_p: pointer to data of fake icmp structure 34897903da2202008733f50e69997029d7a5cfffcb8mreed * 34997903da2202008733f50e69997029d7a5cfffcb8mreed * Return value: 35097903da2202008733f50e69997029d7a5cfffcb8mreed * None 35197903da2202008733f50e69997029d7a5cfffcb8mreed */ 352354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid create_clean_packet(struct icmpv4_fake *fake_p) 35397903da2202008733f50e69997029d7a5cfffcb8mreed{ 354354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct ip4_datagram pkt; /* sending IPv4 packet */ 355354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct icmp4_segment *icmp_p; /* ICMPv4 part of sending packet */ 356354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned short int pkt_size; 357354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 358354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao memset(&pkt, '\0', sizeof(struct ip4_datagram)); 359354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt_size = sizeof(struct iphdr) /* IP header */ 360354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao +sizeof(struct icmphdr) /* ICMP header */ 361354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao +fake_p->data_size; /* ICMP payload */ 362354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 363354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao icmp_p = (struct icmp4_segment *)&(pkt.payload); 364354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 365354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* IPv4 Header */ 366354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.version = 4; 367354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.ihl = sizeof(struct iphdr) / 4; 368354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.tos = 0; 369354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.tot_len = htons(pkt_size); 370354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.id = htons(IPV4_PACKET_ID); 371354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.frag_off = htons(IPV4_DEFAULT_FLAG); 372354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.ttl = IPV4_DEFAULT_TTL; 373354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.protocol = IPPROTO_ICMP; 374354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.check = 0; /* Calculate later */ 375354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.saddr = fake_p->saddr.s_addr; 376354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.daddr = fake_p->daddr.s_addr; 377354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 378354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* ICMPv4 Header */ 379354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao icmp_p->hdr.type = ICMP_ECHO; 380354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao icmp_p->hdr.code = 0; 381354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao icmp_p->hdr.checksum = 0; /* Calculate later */ 382354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao icmp_p->hdr.un.echo.id = htons(ICMP_ECHO_ID); 383354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao icmp_p->hdr.un.echo.sequence = htons(1); 384354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 385354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* ICMPv4 Payload */ 386354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fill_payload(icmp_p->data, fake_p->data_size); 387354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 388354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Calcualte checksums */ 389354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt.hdr.check = calc_checksum((u_int16_t *) (&pkt.hdr), 390354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(struct iphdr)); 391354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao icmp_p->hdr.checksum = calc_checksum((u_int16_t *) icmp_p, 392354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(struct icmphdr) + 393354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->data_size); 394354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 395354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Store the clean packet data */ 396354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->pkt = pkt; 397354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fake_p->pkt_size = pkt_size; 39897903da2202008733f50e69997029d7a5cfffcb8mreed} 39997903da2202008733f50e69997029d7a5cfffcb8mreed 40097903da2202008733f50e69997029d7a5cfffcb8mreed/* 40197903da2202008733f50e69997029d7a5cfffcb8mreed * Function: thrust_fakes() 40297903da2202008733f50e69997029d7a5cfffcb8mreed * 40397903da2202008733f50e69997029d7a5cfffcb8mreed * Description: 40497903da2202008733f50e69997029d7a5cfffcb8mreed * This function thrust fake information to the icmp packet 40597903da2202008733f50e69997029d7a5cfffcb8mreed * 40697903da2202008733f50e69997029d7a5cfffcb8mreed * Argument: 40797903da2202008733f50e69997029d7a5cfffcb8mreed * pkt : Payload of the Ethernet frame (Namely, IPv6 packet 40897903da2202008733f50e69997029d7a5cfffcb8mreed * fake_flag: Flag which represents what information would be faked 40997903da2202008733f50e69997029d7a5cfffcb8mreed * 41097903da2202008733f50e69997029d7a5cfffcb8mreed * Return value: 41197903da2202008733f50e69997029d7a5cfffcb8mreed * None 41297903da2202008733f50e69997029d7a5cfffcb8mreed */ 413354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid thrust_fakes(struct ip4_datagram *pkt, u_int16_t fake_flag) 41497903da2202008733f50e69997029d7a5cfffcb8mreed{ 415354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int rand_val; 416354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao size_t bitsize; 417354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao u_int32_t seed; 418354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 419354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (debug) 420354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "fake_flag = %2x\n", fake_flag); 421354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 422354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_flag & FAKE_VERSION) { /* version */ 423354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bitsize = 4; 424354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao seed = bit_change_seed(bitsize, 1); 425354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.version ^= seed; 42697903da2202008733f50e69997029d7a5cfffcb8mreed } 42797903da2202008733f50e69997029d7a5cfffcb8mreed 428354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_flag & FAKE_IHL) { /* header length */ 429354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bitsize = 4; 430354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao seed = bit_change_seed(bitsize, 1); 431354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.ihl ^= seed; 43297903da2202008733f50e69997029d7a5cfffcb8mreed } 43397903da2202008733f50e69997029d7a5cfffcb8mreed 434354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_flag & FAKE_TOT_LEN) { /* total length */ 435354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bitsize = sizeof(pkt->hdr.tot_len) * 8; 436354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao seed = bit_change_seed(bitsize, bitsize / 8); 437354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.tot_len ^= seed; 43897903da2202008733f50e69997029d7a5cfffcb8mreed } 43997903da2202008733f50e69997029d7a5cfffcb8mreed 440354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_flag & FAKE_FRAGMENT) { /* fragment information */ 441354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Set reserved flag */ 442354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao rand_val = rand() / ((RAND_MAX + 1U) / 16); 443354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!rand_val) { 444354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (debug) 445354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Up reserved bit\n"); 446354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.frag_off |= htonl(0x80000000); 447354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 448354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 449354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Set more fragments flag */ 450354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao rand_val = rand() / ((RAND_MAX + 1U) / 3); 451354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!rand_val) { 452354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (debug) 453354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Set more fragments flag\n"); 454354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.frag_off |= htons(0x2000); 455354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 456354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 457354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Unset unfragmented flag */ 458354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao rand_val = rand() / ((RAND_MAX + 1U) / 3); 459354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!rand_val) { 460354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (debug) 461354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Unset unfragmented flag\n"); 462354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.frag_off &= htons(0xbfff); 463354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 464354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 465354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Set fragment offset */ 466354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao rand_val = rand() / ((RAND_MAX + 1U) / 3); 467354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!rand_val) { 468354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bitsize = 13; 469354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao seed = bit_change_seed(bitsize, 0); 470354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (debug) 471354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Set fragment offset %02x\n", 472354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao seed); 473354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.frag_off |= htons(seed); 474354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 47597903da2202008733f50e69997029d7a5cfffcb8mreed } 47697903da2202008733f50e69997029d7a5cfffcb8mreed 477354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_flag & FAKE_PROTOCOL) { /* protocol */ 478354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao rand_val = rand() / ((RAND_MAX + 1U) / 5); 479354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao switch (rand_val) { 480354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 1: 481354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 2: 482354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (debug) 483354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Bit reverse\n"); 484354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bitsize = sizeof(pkt->hdr.protocol) * 8; 485354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao seed = bit_change_seed(bitsize, 0); 486354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.protocol ^= seed; 487354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 488354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 489354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 3: 490354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 4: 491354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (debug) 492354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Unknown Protocol\n"); 493354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (rand_val) { 494354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int number; 495354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int counter; 496354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (counter = 0; counter <= 0xff; counter++) { 497354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao number = 498354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao rand() / ((RAND_MAX + 1U) / 0x100); 499354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (getprotobynumber(number) == NULL) { 500354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.protocol = number; 501354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 502354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 503354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 50497903da2202008733f50e69997029d7a5cfffcb8mreed } 505354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 506354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 507354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao default: 508354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (debug) 509354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Do nothing\n"); 510354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 51197903da2202008733f50e69997029d7a5cfffcb8mreed } 512354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 51397903da2202008733f50e69997029d7a5cfffcb8mreed 514354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_flag & FAKE_DADDR) { /* destination address */ 515354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bitsize = sizeof(pkt->hdr.daddr) * 8; 516354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao seed = bit_change_seed(bitsize, bitsize / 8); 517354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.daddr ^= seed; 518354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 519354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 520354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Recalculate checksum once */ 521354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.check = 0; 522354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.check = 523354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao calc_checksum((u_int16_t *) & (pkt->hdr), sizeof(struct iphdr)); 524354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 525354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_flag & FAKE_CHECK) { /* checksum */ 526354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bitsize = sizeof(pkt->hdr.check) * 8; 527354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao seed = bit_change_seed(bitsize, bitsize / 8); 528354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt->hdr.check ^= seed; 52997903da2202008733f50e69997029d7a5cfffcb8mreed } 53097903da2202008733f50e69997029d7a5cfffcb8mreed} 53197903da2202008733f50e69997029d7a5cfffcb8mreed 53297903da2202008733f50e69997029d7a5cfffcb8mreed/* 53397903da2202008733f50e69997029d7a5cfffcb8mreed * Function: send_packet() 53497903da2202008733f50e69997029d7a5cfffcb8mreed * 53597903da2202008733f50e69997029d7a5cfffcb8mreed * Description: 53697903da2202008733f50e69997029d7a5cfffcb8mreed * This function sends icmpv4 packet 53797903da2202008733f50e69997029d7a5cfffcb8mreed * 53897903da2202008733f50e69997029d7a5cfffcb8mreed * Argument: 53997903da2202008733f50e69997029d7a5cfffcb8mreed * fake_p: pointer to data of fake icmp structure 54097903da2202008733f50e69997029d7a5cfffcb8mreed * 54197903da2202008733f50e69997029d7a5cfffcb8mreed * Return value: 54297903da2202008733f50e69997029d7a5cfffcb8mreed * None 54397903da2202008733f50e69997029d7a5cfffcb8mreed */ 544354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid send_packets(struct icmpv4_fake *fake_p) 54597903da2202008733f50e69997029d7a5cfffcb8mreed{ 546354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int sock_fd; 547354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int retval; 548354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct ip4_datagram pkt; 549354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao double start_time; 550354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 551354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Open a socket */ 552354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sock_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); 553354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (sock_fd < 0) 554354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fatal_error("socket()"); 555354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 556354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Bind the socket to the physical address */ 557354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao retval = bind(sock_fd, (struct sockaddr *)&(fake_p->saddr_ll), 558354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(struct sockaddr_ll)); 55997903da2202008733f50e69997029d7a5cfffcb8mreed if (retval < 0) 560354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fatal_error("bind()"); 561354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 562354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Set singal hander for SIGHUP */ 563354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao handler.sa_handler = set_signal_flag; 564354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao handler.sa_flags = 0; 565354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (sigfillset(&handler.sa_mask) < 0) 566354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fatal_error("sigfillset()"); 567354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (sigaction(SIGHUP, &handler, NULL) < 0) 568354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fatal_error("sigfillset()"); 569354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 570354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* 571354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao * loop for sending packets 572354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao */ 573354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt = fake_p->pkt; 574354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao start_time = time(NULL); 575354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 576354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (;;) { 577354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_p->fake_flag) { 578354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pkt = fake_p->pkt; 579354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao thrust_fakes(&pkt, fake_p->fake_flag); 580354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 58197903da2202008733f50e69997029d7a5cfffcb8mreed 582354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao retval = sendto(sock_fd, &pkt, fake_p->pkt_size, 0, 583354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (struct sockaddr *)&(fake_p->daddr_ll), 584354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(struct sockaddr_ll)); 585354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (retval < 0) 586354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fatal_error("sendto()"); 587354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 588354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_p->timeout) /* timeout */ 589354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fake_p->timeout < difftime(time(NULL), start_time)) 590354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 59197903da2202008733f50e69997029d7a5cfffcb8mreed 592354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (catch_sighup) /* catch SIGHUP */ 593354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 594354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 59597903da2202008733f50e69997029d7a5cfffcb8mreed 596354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Close the socket */ 597354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(sock_fd); 59897903da2202008733f50e69997029d7a5cfffcb8mreed} 59997903da2202008733f50e69997029d7a5cfffcb8mreed 60097903da2202008733f50e69997029d7a5cfffcb8mreed/* 60197903da2202008733f50e69997029d7a5cfffcb8mreed * 60297903da2202008733f50e69997029d7a5cfffcb8mreed * Function: main() 60397903da2202008733f50e69997029d7a5cfffcb8mreed * 60497903da2202008733f50e69997029d7a5cfffcb8mreed */ 605354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint main(int argc, char *argv[]) 60697903da2202008733f50e69997029d7a5cfffcb8mreed{ 607354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct icmpv4_fake fake_data; 60897903da2202008733f50e69997029d7a5cfffcb8mreed 609354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao debug = 0; 610354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao program_name = strdup(argv[0]); 611354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao srand(getpid()); 61297903da2202008733f50e69997029d7a5cfffcb8mreed 613354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao memset(&fake_data, '\0', sizeof(struct icmpv4_fake)); 614354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao parse_options(argc, argv, &fake_data); 61597903da2202008733f50e69997029d7a5cfffcb8mreed 616354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao complete_eth_addrs(&fake_data); 617354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao create_clean_packet(&fake_data); 61897903da2202008733f50e69997029d7a5cfffcb8mreed 619354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao send_packets(&fake_data); 62097903da2202008733f50e69997029d7a5cfffcb8mreed 621354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(EXIT_SUCCESS); 622ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 623