/*
* File: mps.c
*
* Description: Multi-functional Packet Sender.
*
* Author: llliu
*
* Date: 2008-11-22
*
* Usage:
* mps -s [source-ip source-port] -d [dest-ip dest-port] -p [icmp/tcp/udp] -l [pkt-len] -i [ms] -c [count] -I [interface]
*
*
*/
#include "mps.h"
#include "version.h"
char send_pkt[1518];
_iphdr ipheader;
_icmphdr icmpheader;
_tcphdr tcpheader;
_udphdr udpheader;
psdhdr _psdhdr;
struct sockaddr_in sockAddr;
/*
* get source ip.
*/
struct sockaddr_in source;
char *device = "eth0";
volatile int exiting;
static void usage(void) __attribute__((noreturn));
__u16 checksum(__u16 *buffer, int size)
{
unsigned long cksum=0;
while(size >1) {
cksum+=*buffer++;
size-=sizeof(__u16);
}
if(size) cksum+=*(__u8*)buffer;
cksum=(cksum >> 16)+(cksum&0xffff);
cksum+=(cksum >>16);
return (__u16)(~cksum);
}
#define ICMP_ECHO 8 /* Echo Request */
static int build_icmp(int pkt_len)
{
int send_pkt_size;
int data_len;
unsigned char *append_buffer;
data_len = pkt_len - MACHDRSIZE - sizeof(_iphdr) - sizeof(icmpheader);
assert(data_len >= 0);
append_buffer = (unsigned char *)malloc(data_len);
icmpheader.type = ICMP_ECHO;
icmpheader.code = 1;
icmpheader.checksum = 0;
icmpheader.id = htons(12345);
icmpheader.seq = htons(1);
/*
* build the packet.
*/
memcpy(send_pkt, &ipheader, sizeof(ipheader));
memcpy(send_pkt + sizeof(ipheader), &icmpheader, sizeof(icmpheader));
memcpy(send_pkt + sizeof(ipheader) + sizeof(icmpheader),
append_buffer,
data_len);
send_pkt_size = sizeof(ipheader) + sizeof(icmpheader) + data_len;
icmpheader.checksum = checksum((__u16 *)(send_pkt+sizeof(ipheader)),
send_pkt_size - sizeof(ipheader));
memcpy(send_pkt+sizeof(ipheader), &icmpheader, sizeof(icmpheader));
memcpy(send_pkt + sizeof(ipheader) + sizeof(icmpheader),
append_buffer,
data_len);
ipheader.checksum = checksum((__u16 *)send_pkt, send_pkt_size);
memcpy(send_pkt, &ipheader, sizeof(ipheader));
return send_pkt_size;
}
static int build_tcp(__u16 sport, __u16 dport, int pkt_len)
{
int send_pkt_size;
int data_len;
unsigned char *append_buffer;
data_len = pkt_len - MACHDRSIZE - sizeof(_iphdr) - sizeof(tcpheader);
assert(data_len >= 0);
append_buffer = (unsigned char *)malloc(data_len);
tcpheader.th_dport= htons(dport);
tcpheader.th_sport = htons(sport);
tcpheader.th_seq = htonl(SENDTCPSEQ);
tcpheader.th_ack = 0;
/*
* TODO: pkt_len
*/
tcpheader.th_lenres =(sizeof(_tcphdr)/4<<4|0);
//tcpheader.th_lenres =((sizeof(_tcphdr) + data_len)/4<<4|0);
tcpheader.th_flag = 2;
tcpheader.th_win = htons(16384);
tcpheader.th_urp = 0;
tcpheader.th_sum = 0;
_psdhdr.saddr=ipheader.sourceIP;
_psdhdr.daddr=ipheader.destIP;
_psdhdr.mbz=0;
_psdhdr.ptcl=IPPROTO_TCP;
/*
* TODO: pkt_len
*/
_psdhdr.tcpl = htons(sizeof(tcpheader) + data_len);
/*
*
*/
ipheader.checksum = 0;
tcpheader.th_sum = 0;
/*
* psdhdr + tcpheader + data.
*/
memcpy(send_pkt,&_psdhdr,sizeof(_psdhdr));
memcpy(send_pkt+sizeof(_psdhdr),&tcpheader,sizeof(tcpheader));
memcpy(send_pkt+sizeof(_psdhdr)+sizeof(tcpheader), append_buffer, data_len);
free(append_buffer);
tcpheader.th_sum=checksum((__u16 *)send_pkt,sizeof(_psdhdr)+sizeof(tcpheader) + data_len);
/*
* the actual packet.
*/
memcpy(send_pkt,&ipheader,sizeof(ipheader));
memcpy(send_pkt+sizeof(ipheader),&tcpheader,sizeof(tcpheader));
memcpy(send_pkt+sizeof(ipheader)+sizeof(tcpheader), append_buffer, data_len);
//memset(send_pkt+sizeof(ipheader)+sizeof(tcpheader),0,4);
send_pkt_size=sizeof(ipheader)+sizeof(tcpheader) + data_len;
ipheader.checksum=checksum((__u16 *)send_pkt,send_pkt_size);
memcpy(send_pkt,&ipheader,sizeof(ipheader));
return send_pkt_size;
}
static int send_udp(__u16 sport, __u16 dport, int pkt_len)
{
int send_pkt_size;
int data_len;
unsigned char *append_buffer;
data_len = pkt_len - MACHDRSIZE - sizeof(_iphdr) - sizeof(udpheader);
assert(data_len >= 0);
append_buffer = (unsigned char *)malloc(data_len);
udpheader.dport= htons(dport);
udpheader.sport = htons(sport);
udpheader.len = htons(sizeof(udpheader) + data_len);
udpheader.checksum = 0;
/*
* TODO: pkt_len
*/
_psdhdr.saddr=ipheader.sourceIP;
_psdhdr.daddr=ipheader.destIP;
_psdhdr.mbz=0;
_psdhdr.ptcl=IPPROTO_UDP;
/*
* TODO: pkt_len
*/
_psdhdr.tcpl = htons(sizeof(udpheader) + data_len);
ipheader.checksum = 0;
/*
* psdhdr + udpheader + data.
*/
memcpy(send_pkt,&_psdhdr,sizeof(_psdhdr));
memcpy(send_pkt+sizeof(_psdhdr),&udpheader,sizeof(udpheader));
memcpy(send_pkt+sizeof(_psdhdr)+sizeof(udpheader), append_buffer, data_len);
free(append_buffer);
udpheader.checksum = checksum((__u16 *)send_pkt,
sizeof(_psdhdr) + sizeof(udpheader) + data_len);
/*
* the actual packet.
*/
memcpy(send_pkt,&ipheader,sizeof(ipheader));
memcpy(send_pkt+sizeof(ipheader),&udpheader,sizeof(udpheader));
memcpy(send_pkt+sizeof(ipheader)+sizeof(udpheader), append_buffer, data_len);
send_pkt_size = sizeof(ipheader) + sizeof(udpheader) + data_len;
ipheader.checksum = checksum((__u16 *)send_pkt, send_pkt_size);
memcpy(send_pkt, &ipheader, sizeof(ipheader));
return send_pkt_size;
}
static Boolean protocol_check(char *protocol, int *id)
{
if (strcmp(protocol, "icmp") == 0) {
*id = IPPROTO_ICMP;
return TRUE;
}
else if (strcmp(protocol, "tcp") == 0) {
*id = IPPROTO_TCP;
return TRUE;
}
else if (strcmp(protocol, "udp") == 0) {
*id = IPPROTO_UDP;
return TRUE;
}
else {
return FALSE;
}
}
static int is_ip(char *ip)
{
int dot[4];
int a;
char *leg;
int leg_cnt = 0;
leg = strchr(ip,'.');
while(leg_cnt <= 4) {
if(leg) {
leg++;
leg_cnt++;
leg = strchr(leg,'.');
}
else
break;
}
if(leg_cnt != 3) {
//printf("illegal ip\n");
return -1;
}
sscanf(ip,"%d.%d.%d.%d",&dot[0],&dot[1],&dot[2],&dot[3]);
for(a = 0;a < 3;a++) {
if(dot[a] < 0 || dot[a] > 255) {
printf("IP:%s format:dot[%d]:%d\n",ip,a,dot[a]);
return -1;
}
}
return 0;
}
__attribute__((used)) static char *ip_to_str(__u32 ip)
{
static char buffer[100];
memset(buffer, 0, 100);
sprintf(buffer, "%u.%u.%u.%u", IPTOSTR(ip));
return buffer;
}
static void sigexit(int signo)
{
exiting = 1;
}
int main(int argc, char **argv)
{
char *options = "s:d:p:l:i:c:I:Vh";
int ch;
int skfd;
int send_pkt_size;
int rtn;
int map;
__u32 send_cnt;
__u32 sip, dip;
__u16 sport, dport;
char *protocol;
int protocol_id;
int pkt_len;
double interval;
int count;
map = 0;
send_cnt = 0;
rtn = 0;
sip = 0;
dip = 0;
sport = 0;
dport = 0;
protocol = "icmp";
protocol_id = IPPROTO_ICMP;
pkt_len = 64;
interval = 1000000;
count = 0;
while ((ch = getopt(argc, argv, options)) != -1) {
switch (ch) {
case 's':
if (is_ip(optarg)) {
printf("Argument-Error: optarg:%s not ip address format.\n", optarg);
exit(2);
}
sip = inet_addr(optarg);
sport = atoi(argv[optind]);
if (sport == 0) {
sport = 65535;
}
break;
case 'd':
if (is_ip(optarg)) {
printf("Argument-Error: optarg:%s not ip address format.\n", optarg);
exit(2);
}
dip = inet_addr(optarg);
dport = atoi(argv[optind]);
if (dport == 0) {
dport = 65535;
}
break;
case 'p':
protocol = optarg;
if (protocol_check(protocol, &protocol_id) == FALSE) {
printf("Argument-Error: %s bad protocol name, should be [icmp/udp/tcp].\n", protocol);
exit (-1);
}
break;
case 'l':
pkt_len = atoi(optarg);
break;
case 'i':
interval = (atof(optarg) * 1000000);
break;
case 'c':
count = atoi(optarg);
break;
case 'I':
if (inet_pton(AF_INET, optarg, &source.sin_addr) > 0) {
assert(0);
exit(2);
}
else {
device = optarg;
}
break;
case 'V':
printf("Multi-functional Packet Sender, %s\n", VERSION);
exit(0);
case 'h':
usage();
default:
usage();
}
}
//argc -= optind;
//argv += optind;
if (argc == 1) {
usage();
}
if (dip == 0) {
printf("Argume
评论0