blob: 485f1206e507bad8e213253267cf125949186b63 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#define __FAVOR_BSD
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <bits/ioctls.h>
#include <net/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <sys/time.h>
#include <errno.h>
// Define some constants.
#define IP6_HDRLEN 40 // IPv6 header length
#define UDP_HDRLEN 8 // UDP header length, excludes data
#define TIMEOUT 54824
#define PACKET_SIZE 4096
typedef enum {
TUPLE_DESTORY = 0,
TUPLE_ADD = 1,
TUPLE_DEL = 2,
}TUPLE_CMD;
int DES_PORT = 80;
int LOCAL_PORT = 8888;
void usage(char *name);
void send_tcp(int sock, int if_random, struct sockaddr_in * serveraddr,
struct sockaddr_in * clientaddr);
void send_udp(int sock, int if_random, struct sockaddr_in * serveraddr,
struct sockaddr_in * clientaddr);
void send_icmp(int sock, int if_random, struct sockaddr_in * serveraddr,
struct sockaddr_in * clientaddr);
void send_tcp6(int sock, char *src, char * dst);
void send_udp6(int sock, char *src, char * dst);
void send_icmpv6(int sock, char *src, char * dst);
static int handle_tuple(TUPLE_CMD cmd, int version, char *src_ip,
char *dst_ip, int sport, int dport, int proto)
{
FILE *fp;
char write_buf[100] = {0};
int ret = 0;
fp = fopen("/sys/kernel/mpipe/database/tuple", "a+");
if(fp == NULL)
{
printf("handle_tuple: /sys/kernel/mpipe/database/tuple is not exit\n");
return -1;
}
snprintf(write_buf, sizeof(write_buf), "%u %u %s %s %u %u %u\r\n", cmd, version, src_ip, dst_ip, sport, dport, proto);
if(fwrite(write_buf, 1, strlen(write_buf), fp ) != strlen(write_buf))
{
printf("handle_tuple: file write error (size=%d)\n", strlen(write_buf));
ret = -1;
}
fclose(fp);
return ret;
}
int main(int argc, char *argv[])
{
int d_port = 0,s_port = 0;
int sock, c;
int if_random = 0;
int on = 1;
int net_ip = 6;
int version = 4;
struct sockaddr_in serveraddr, clientaddr;
char *dst = "2.2.2.2", *src = "1.1.1.1";
char *dst6 = "ff02::2", *src6 = "ff02::1";
char *des_port = "-x", *src_port = "-x";
char *net_type = "icmp";
struct timeval timeo;
while ((c = getopt(argc, argv, "v:a:b:d:s:t:p:h")) != EOF) {
switch(c)
{
case 'v':
version = atoi(optarg);
break;
case 'a':
src_port = optarg;
break;
case 'b':
des_port = optarg;
break;
case 'd':
dst = optarg;
dst6 = optarg;
break;
case 's':
src = optarg;
src6 = optarg;
if_random = 1;
break;
case 't':
net_type = optarg;
break;
case 'h':
usage(argv[0]);
exit(1);
default:
exit(0);
}
}
if (strcmp(net_type, "icmp")==0)
net_ip = 1;
else if (strcmp(net_type, "icmpv6")==0)
net_ip = 58;
else if (strcmp(net_type, "udp")==0)
net_ip = 17;
else
net_ip = 6;
if (strcmp(src_port, "-x")) {
s_port = atoi(src_port);
LOCAL_PORT = s_port;
}
if (strcmp(des_port,"-x")) {
d_port = atoi(des_port);
DES_PORT = d_port;
}
printf("s_port=%d---d_port=%d\n", s_port, d_port);
if (version == 4) {
bzero(&serveraddr,sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(DES_PORT);
if (inet_pton(AF_INET, dst, &serveraddr.sin_addr) != 1) {
printf("wrong in inet_pthon \n");
exit(1);
}
printf("destination address:%s\n", inet_ntoa(serveraddr.sin_addr));
bzero(&clientaddr, sizeof(struct sockaddr_in));
clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons(LOCAL_PORT);
if (inet_pton(AF_INET, src, &clientaddr.sin_addr) != 1) {
printf("wrong in inet_pthon \n");
exit(1);
}
printf("source address:%s\n", inet_ntoa(clientaddr.sin_addr));
timeo.tv_sec = TIMEOUT / 1000;
timeo.tv_usec = TIMEOUT % 1000;
switch(net_ip)
{
case 1:
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
fprintf(stdout, "create socket error\n");
exit(0);
}
printf("the sock=%d\n",sock);
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
setuid(getpid());
send_icmp(sock, if_random, &serveraddr, &clientaddr);
break;
case 6:
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
fprintf(stdout, "create socket error\n");
exit(0);
}
printf("the sock=%d\n", sock);
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
setuid(getpid());
send_tcp(sock, if_random, &serveraddr, &clientaddr);
break;
case 17:
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) < 0) {
fprintf(stdout, "create socket error\n");
exit(0);
}
printf("the sock=%d\n", sock);
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
setuid(getpid());
send_udp(sock, if_random, &serveraddr, &clientaddr);
break;
}
}else if(version == 6) {
if ((sock = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror ("create socket() failed ");
exit (EXIT_FAILURE);
}
printf("the sock=%d\n",sock);
switch(net_ip)
{
case 58:
send_icmpv6(sock, src6, dst6);
break;
case 6:
send_tcp6(sock, src6, dst6);
break;
case 17:
send_udp6(sock, src6, dst6);
break;
}
}
}
static uint16_t cal_chksum (uint16_t *addr, int len)
{
int count = len;
register uint32_t sum = 0;
uint16_t answer = 0;
while (count > 1) {
sum += *(addr++);
count -= 2;
}
if (count > 0) {
sum += *(uint8_t *) addr;
}
while (sum >> 16) {
sum = (sum & 0xffff) + (sum >> 16);
}
answer = ~sum;
return (answer);
}
static uint16_t tcp6_checksum (struct ip6_hdr *iphdr, struct tcphdr *tcphdr)
{
uint32_t lvalue;
char buf[IP_MAXPACKET], cvalue;
char *ptr;
int chksumlen = 0;
ptr = &buf[0];
memcpy (ptr, &iphdr->ip6_src, sizeof (iphdr->ip6_src));
ptr += sizeof (iphdr->ip6_src);
chksumlen += sizeof (iphdr->ip6_src);
memcpy (ptr, &iphdr->ip6_dst, sizeof (iphdr->ip6_dst));
ptr += sizeof (iphdr->ip6_dst);
chksumlen += sizeof (iphdr->ip6_dst);
lvalue = htonl(sizeof(tcphdr));
memcpy (ptr, &lvalue, sizeof (lvalue));
ptr += sizeof (lvalue);
chksumlen += sizeof (lvalue);
*ptr = 0; ptr++;
*ptr = 0; ptr++;
*ptr = 0; ptr++;
chksumlen += 3;
memcpy (ptr, &iphdr->ip6_nxt, sizeof (iphdr->ip6_nxt));
ptr += sizeof (iphdr->ip6_nxt);
chksumlen += sizeof (iphdr->ip6_nxt);
memcpy (ptr, &tcphdr->th_sport, sizeof (tcphdr->th_sport));
ptr += sizeof (tcphdr->th_sport);
chksumlen += sizeof (tcphdr->th_sport);
memcpy (ptr, &tcphdr->th_dport, sizeof (tcphdr->th_dport));
ptr += sizeof (tcphdr->th_dport);
chksumlen += sizeof (tcphdr->th_dport);
memcpy (ptr, &tcphdr->th_seq, sizeof (tcphdr->th_seq));
ptr += sizeof (tcphdr->th_seq);
chksumlen += sizeof (tcphdr->th_seq);
memcpy (ptr, &tcphdr->th_ack, sizeof (tcphdr->th_ack));
ptr += sizeof (tcphdr->th_ack);
chksumlen += sizeof (tcphdr->th_ack);
cvalue = (tcphdr->th_off << 4) + tcphdr->th_x2;
memcpy (ptr, &cvalue, sizeof (cvalue));
ptr += sizeof (cvalue);
chksumlen += sizeof (cvalue);
memcpy (ptr, &tcphdr->th_flags, sizeof (tcphdr->th_flags));
ptr += sizeof (tcphdr->th_flags);
chksumlen += sizeof (tcphdr->th_flags);
memcpy (ptr, &tcphdr->th_win, sizeof (tcphdr->th_win));
ptr += sizeof (tcphdr->th_win);
chksumlen += sizeof (tcphdr->th_win);
*ptr = 0; ptr++;
*ptr = 0; ptr++;
chksumlen += 2;
memcpy (ptr, &tcphdr->th_urp, sizeof (tcphdr->th_urp));
ptr += sizeof (tcphdr->th_urp);
chksumlen += sizeof (tcphdr->th_urp);
return cal_chksum ((uint16_t *) buf, chksumlen);
}
static uint16_t udp6_checksum (struct ip6_hdr *iphdr, struct udphdr *udphdr, uint8_t *payload, int payloadlen)
{
char buf[IP_MAXPACKET];
char *ptr;
int chksumlen = 0;
int i;
ptr = &buf[0];
memcpy (ptr, &iphdr->ip6_src.s6_addr, sizeof (iphdr->ip6_src.s6_addr));
ptr += sizeof (iphdr->ip6_src.s6_addr);
chksumlen += sizeof (iphdr->ip6_src.s6_addr);
memcpy (ptr, &iphdr->ip6_dst.s6_addr, sizeof (iphdr->ip6_dst.s6_addr));
ptr += sizeof (iphdr->ip6_dst.s6_addr);
chksumlen += sizeof (iphdr->ip6_dst.s6_addr);
memcpy (ptr, &udphdr->len, sizeof (udphdr->len));
ptr += sizeof (udphdr->len);
chksumlen += sizeof (udphdr->len);
*ptr = 0; ptr++;
*ptr = 0; ptr++;
*ptr = 0; ptr++;
chksumlen += 3;
memcpy (ptr, &iphdr->ip6_nxt, sizeof (iphdr->ip6_nxt));
ptr += sizeof (iphdr->ip6_nxt);
chksumlen += sizeof (iphdr->ip6_nxt);
memcpy (ptr, &udphdr->source, sizeof (udphdr->source));
ptr += sizeof (udphdr->source);
chksumlen += sizeof (udphdr->source);
memcpy (ptr, &udphdr->dest, sizeof (udphdr->dest));
ptr += sizeof (udphdr->dest);
chksumlen += sizeof (udphdr->dest);
memcpy (ptr, &udphdr->len, sizeof (udphdr->len));
ptr += sizeof (udphdr->len);
chksumlen += sizeof (udphdr->len);
*ptr = 0; ptr++;
*ptr = 0; ptr++;
chksumlen += 2;
memcpy (ptr, payload, payloadlen * sizeof (uint8_t));
ptr += payloadlen;
chksumlen += payloadlen;
for (i=0; i<payloadlen%2; i++, ptr++) {
*ptr = 0;
ptr++;
chksumlen++;
}
return cal_chksum ((uint16_t *) buf, chksumlen);
}
void send_tcp(int sock, int if_random, struct sockaddr_in * serveraddr,
struct sockaddr_in * clientaddr)
{
int maxfds = 0;
int headerlen, i, n;
fd_set readfds;
int tcp_flags[8];
char src_ip[16] = {0};
char dst_ip[16] = {0};
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
struct ip *myip, *from_iph;
struct tcphdr *mytcp, *from_tcp;
struct timeval timeo;
struct sockaddr_in from;
printf("-----------------------------\n");
bzero(sendpacket, sizeof(sendpacket));
myip = (struct ip*)sendpacket;
myip->ip_v = IPVERSION;
printf("the myip->ip_v is %d\n", myip->ip_v);
myip->ip_hl = sizeof(struct ip) >> 2;
printf("the myip->ip_hl is %d\n", myip->ip_hl);
myip->ip_tos = 0;
myip->ip_id = 0;
myip->ip_off = 0;
myip->ip_ttl = MAXTTL;
myip->ip_p = IPPROTO_TCP;
myip->ip_sum = 0;
myip->ip_dst = serveraddr->sin_addr;
printf("destination address:%s\n", inet_ntoa(myip->ip_dst));
mytcp = (struct tcphdr*)(sendpacket + sizeof(struct ip));
mytcp->th_sport = htons(LOCAL_PORT);
printf("the sport is %d\n", LOCAL_PORT);
mytcp->th_dport = htons(DES_PORT);
printf("the dport is %d\n", DES_PORT);
mytcp->th_seq = htonl (0);
mytcp->th_ack = htonl (0);
mytcp->th_x2 = 0;
mytcp->th_off = sizeof(struct tcphdr) >> 2;
tcp_flags[0] = 0;
tcp_flags[1] = 1;
tcp_flags[2] = 0;
tcp_flags[3] = 0;
tcp_flags[4] = 0;
tcp_flags[5] = 0;
tcp_flags[6] = 0;
tcp_flags[7] = 0;
mytcp->th_flags = 0;
for (i=0; i<8; i++) {
mytcp->th_flags += (tcp_flags[i] << i);
}
mytcp->th_win = htons (65535);
mytcp->th_urp = htons (0);
mytcp->th_sum = 0;
headerlen = sizeof(struct ip) + sizeof(struct tcphdr);
printf("the headerlen is %d\n", headerlen);
myip->ip_len = htons(headerlen);
printf("the myip->ip_len is %d\n", ntohs(myip->ip_len));
for(i = 0; i < 10; i++) {
if (if_random == 0) {
myip->ip_src.s_addr = random();
printf("This is the %d time to send the tcp packet----", i+1);
printf("from source address:%s--src_port:%d--->", inet_ntoa(myip->ip_src), LOCAL_PORT);
printf("destination address:%s--des_port:%d\n", inet_ntoa(myip->ip_dst), DES_PORT);
} else {
myip->ip_src = clientaddr->sin_addr;
printf("This is the %d time to send the tcp packet----", i+1);
printf("from source address:%s--src_port:%d--->", inet_ntoa(myip->ip_src), LOCAL_PORT);
printf("destination address:%s--des_port:%d\n", inet_ntoa(myip->ip_dst), DES_PORT);
}
memcpy(src_ip, inet_ntoa(myip->ip_src), 16);
memcpy(dst_ip, inet_ntoa(myip->ip_dst), 16);
handle_tuple(TUPLE_ADD, IPVERSION, src_ip, dst_ip, LOCAL_PORT, DES_PORT, IPPROTO_TCP);
sendto(sock, sendpacket, headerlen, 0, (struct sockaddr*)serveraddr, sizeof(struct sockaddr_in));
timeo.tv_sec = TIMEOUT / 1000;
timeo.tv_usec = TIMEOUT % 1000;
while(1) {
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
maxfds = sock + 1;
n = select(maxfds, &readfds, NULL, NULL, &timeo);
if (n <= 0) {
printf("Error: select FD time out\n");
close(sock);
return;
}
memset(recvpacket, 0, sizeof(recvpacket));
unsigned int fromlen = sizeof(from);
n = recvfrom(sock, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)(&from), &fromlen);
if (n < 1)
break;
char from_ip[16];
memcpy(from_ip, inet_ntoa(from.sin_addr), 16);
printf("receive pkt from ip: %s, ",from_ip);
if (strcmp(from_ip, inet_ntoa(serveraddr->sin_addr)) != 0) {
printf("expect ip:%s, ip wrong\n", inet_ntoa(serveraddr->sin_addr));
break;
}
from_iph = (struct ip *)recvpacket;
from_tcp = (struct tcphdr *)(recvpacket + (from_iph->ip_hl<<2));
if (from_tcp->th_sport == mytcp->th_dport && from_tcp->th_dport == mytcp->th_sport) {
printf("tcp response was received successfully!\n");
break;
} else {
printf("Error: failed to received tcp response!\n");
continue;
}
}
usleep(1000*500);
}
close(sock);
printf("-----------------------------\n");
}
void send_udp(int sock, int if_random, struct sockaddr_in * serveraddr,
struct sockaddr_in * clientaddr)
{
int maxfds = 0;
int headerlen, i, n;
fd_set readfds;
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
char src_ip[16] = {0};
char dst_ip[16] = {0};
char *data;
struct ip *myip, *from_iph;
struct udphdr *myudp, *from_udp;
struct timeval timeo;
struct sockaddr_in from;
printf("-----------------------------\n");
bzero(sendpacket, sizeof(sendpacket));
myip = (struct ip*)sendpacket;
myip->ip_v = IPVERSION;
printf("the myip->ip_v is %d\n", myip->ip_v);
myip->ip_hl = sizeof(struct ip) >> 2;
printf("the myip->ip_hl is %d\n", myip->ip_hl);
myip->ip_tos = 0;
myip->ip_id = 0;
myip->ip_off = 0;
myip->ip_ttl = IPDEFTTL;
myip->ip_p = IPPROTO_UDP;
myip->ip_sum = 0;
myip->ip_dst = serveraddr->sin_addr;
printf("destination address:%s\n", inet_ntoa(myip->ip_dst));
myudp = (struct udphdr*)(sendpacket + sizeof(struct ip));
myudp->source = htons(LOCAL_PORT);
printf("the sport is %d\n", ntohs(myudp->source));
myudp->dest = serveraddr->sin_port;
printf("the dport is %d\n", ntohs(serveraddr->sin_port));
data = (char*)(sendpacket + sizeof(struct ip) + sizeof(struct udphdr));
memcpy(data, myip, sizeof(struct ip));
myudp->len = htons(sizeof(struct ip) + sizeof(struct udphdr));
myudp->check=0;
headerlen = sizeof(struct ip) + sizeof(struct udphdr) + sizeof(struct ip);
printf("the headerlen is %d\n", headerlen);
myip->ip_len = htons(headerlen);
printf("the myip->ip_len is %d\n", ntohs(myip->ip_len));
for(i = 0; i < 10; i++) {
if (if_random == 0) {
myip->ip_src.s_addr = random();
printf("This is the %d time to send the udp packet----", i+1);
printf("from source address:%s--src_port:%d--->", inet_ntoa(myip->ip_src), LOCAL_PORT);
printf("destination address:%s--des_port:%d\n", inet_ntoa(myip->ip_dst), DES_PORT);
} else {
myip->ip_src=clientaddr->sin_addr;
printf("This is the %d time to send the udp packet----",i+1);
printf("from source address:%s--src_port:%d--->",inet_ntoa(myip->ip_src),LOCAL_PORT);
printf("destination address:%s--des_port:%d\n",inet_ntoa(myip->ip_dst),DES_PORT);
}
memcpy(src_ip, inet_ntoa(myip->ip_src), 16);
memcpy(dst_ip, inet_ntoa(myip->ip_dst), 16);
handle_tuple(TUPLE_ADD, IPVERSION, src_ip, dst_ip, LOCAL_PORT, DES_PORT, IPPROTO_UDP);
sendto(sock, sendpacket, headerlen, 0, (struct sockaddr*)serveraddr, sizeof(struct sockaddr_in));
timeo.tv_sec = TIMEOUT / 1000;
timeo.tv_usec = TIMEOUT % 1000;
while(1) {
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
maxfds = sock + 1;
n = select(maxfds, &readfds, NULL, NULL, &timeo);
if (n <= 0) {
printf("Error: select FD time out\n");
close(sock);
return;
}
memset(recvpacket, 0, sizeof(recvpacket));
unsigned int fromlen = sizeof(from);
n = recvfrom(sock, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)(&from), &fromlen);
if (n < 1)
break;
char from_ip[16];
memcpy(from_ip, inet_ntoa(from.sin_addr), 16);
printf("receive pkt from ip: %s, ",from_ip);
if (strcmp(from_ip, inet_ntoa(serveraddr->sin_addr)) != 0) {
printf("expect ip:%s, ip wrong\n", inet_ntoa(serveraddr->sin_addr));
break;
}
from_iph = (struct ip *)recvpacket;
from_udp = (struct udphdr *)(recvpacket + (from_iph->ip_hl<<2));
if (from_udp->source == myudp->dest && from_udp->dest == myudp->source) {
printf("udp response was received successfully!\n");
break;
} else {
printf("Error: failed to received udp response!\n");
continue;
}
}
usleep(1000*500);
}
close(sock);
printf("-----------------------------\n");
}
void send_icmp(int sock, int if_random, struct sockaddr_in * serveraddr,
struct sockaddr_in * clientaddr)
{
int len, datalen = 56;
int nsent = 0;
int headerlen, i, n;
int maxfds = 0;
fd_set readfds;
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
char src_ip[16] = {0};
char dst_ip[16] = {0};
struct ip *myip, *from_iph;
struct icmp *myicmp, *from_icmp;
struct timeval timeo;
struct sockaddr_in from;
printf("-----------------------------\n");
bzero(sendpacket, sizeof(sendpacket));
headerlen = sizeof(struct ip) + sizeof(struct icmp);
printf("the headerlen is %d\n", headerlen);
myip = (struct ip*)sendpacket;
myip->ip_v = IPVERSION;
printf("the myip->ip_v is %d\n", myip->ip_v);
myip->ip_hl = sizeof(struct ip) >> 2;
printf("the myip->ip_hl is %d\n", myip->ip_hl);
myip->ip_len = htons(headerlen);
printf("the myip->ip_len is %d\n", ntohs(myip->ip_len));
myip->ip_tos = 0;
myip->ip_id = 0;
myip->ip_off = 0;
myip->ip_ttl = IPDEFTTL;
myip->ip_p = IPPROTO_ICMP;
myip->ip_sum = 0;
myip->ip_dst = serveraddr->sin_addr;
printf("destination address:%s\n", inet_ntoa(myip->ip_dst));
myicmp = (struct icmp*)(sendpacket + sizeof(struct ip));
myicmp->icmp_type = ICMP_ECHO;
myicmp->icmp_code = 0;
myicmp->icmp_id = htons(getpid());
gettimeofday((struct timeval *)myicmp->icmp_data, NULL);
len = 8 + datalen;
for(i = 0; i < 10; i++) {
if (if_random == 0) {
myip->ip_src.s_addr = random();
myicmp->icmp_seq = htons(nsent++);
myicmp->icmp_cksum = 0;
myicmp->icmp_cksum = cal_chksum((unsigned short *)myicmp, len);
printf("This is the %d time to send the icmp packet----", i+1);
printf("from source address:%s--->", inet_ntoa(myip->ip_src));
printf("destination address:%s\n", inet_ntoa(myip->ip_dst));
} else {
myip->ip_src = clientaddr->sin_addr;
myicmp->icmp_seq = htons(nsent++);
myicmp->icmp_cksum = 0;
myicmp->icmp_cksum = cal_chksum((unsigned short *)myicmp, len);
printf("This is the %d time to send the icmp packet----", i+1);
printf("from source address:%s--->", inet_ntoa(myip->ip_src));
printf("destination address:%s\n", inet_ntoa(myip->ip_dst));
}
memcpy(src_ip, inet_ntoa(myip->ip_src), 16);
memcpy(dst_ip, inet_ntoa(myip->ip_dst), 16);
handle_tuple(TUPLE_ADD, IPVERSION, src_ip, dst_ip,
myicmp->icmp_id, (myicmp->icmp_type << 8) | myicmp->icmp_code, IPPROTO_ICMP);
sendto(sock, sendpacket, len, 0, (struct sockaddr*)serveraddr, sizeof(struct sockaddr_in));
timeo.tv_sec = TIMEOUT / 1000;
timeo.tv_usec = TIMEOUT % 1000;
while(1) {
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
maxfds = sock + 1;
n = select(maxfds, &readfds, NULL, NULL, &timeo);
if (n <= 0) {
printf("Error: select FD time out\n");
close(sock);
return;
}
memset(recvpacket, 0, sizeof(recvpacket));
unsigned int fromlen = sizeof(from);
n = recvfrom(sock, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)(&from), &fromlen);
if (n < 1)
break;
char from_ip[16];
memcpy(from_ip, inet_ntoa(from.sin_addr), 16);
printf("receive pkt from ip: %s, ",from_ip);
if (strcmp(from_ip, inet_ntoa(serveraddr->sin_addr)) != 0) {
printf("expect ip:%s, ip wrong\n", inet_ntoa(serveraddr->sin_addr));
continue;
}
from_iph = (struct ip *)recvpacket;
from_icmp = (struct icmp *)(recvpacket + (from_iph->ip_hl<<2));
if (from_icmp->icmp_type == ICMP_ECHOREPLY && from_icmp->icmp_id == htons(getpid())) {
printf("icmp echo reply was received successfully!\n");
break;
} else {
printf("Error: failed to received icmp echo reply!\n");
continue;
}
}
usleep(1000*500);
}
close(sock);
printf("-----------------------------\n");
}
void send_tcp6(int sock, char *src, char * dst)
{
int len;
int maxfds = 0;
int i, status, n;
int tcp_flags[8];
fd_set readfds;
char src_ip[46] = {0};
char dst_ip[46] = {0};
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
struct ip6_hdr *myip6, *from_ip6h;
struct tcphdr *mytcp, *from_tcp;
struct sockaddr_in6 from;
struct sockaddr_in6 server6addr;
struct timeval timeo;
printf("-----------------------------\n");
strcpy (src_ip, src);
strcpy (dst_ip, dst);
printf("source address:%s\n", src_ip);
printf("destination address:%s\n", dst_ip);
bzero(&server6addr, sizeof(struct sockaddr_in6));
server6addr.sin6_family = AF_INET6;
server6addr.sin6_port = htons(0);
if (inet_pton(AF_INET6, dst_ip, &server6addr.sin6_addr) != 1) {
printf("wrong in inet_pthon \n");
exit(1);
}
bzero(sendpacket, sizeof(sendpacket));
myip6 = (struct ip6_hdr*)(sendpacket);
myip6->ip6_flow = htonl((6 << 28) | (0 << 20) | 0);
myip6->ip6_plen = htons(sizeof(struct tcphdr));
myip6->ip6_nxt = IPPROTO_TCP;
myip6->ip6_hops = 255;
if ((status = inet_pton (AF_INET6, src_ip, &(myip6->ip6_src))) != 1) {
fprintf (stderr, "inet_pton() failed.\nError message: %s", strerror (status));
exit (EXIT_FAILURE);
}
if ((status = inet_pton (AF_INET6, dst_ip, &(myip6->ip6_dst))) != 1) {
fprintf (stderr, "inet_pton() failed.\nError message: %s", strerror (status));
exit (EXIT_FAILURE);
}
mytcp = (struct tcphdr*)(sendpacket + sizeof(struct ip6_hdr) );
mytcp->th_sport = htons(LOCAL_PORT);
printf("the sport is %d\n", LOCAL_PORT);
mytcp->th_dport = htons(DES_PORT);
printf("the dport is %d\n", DES_PORT);
mytcp->th_seq = htonl (0);
mytcp->th_ack = htonl (0);
mytcp->th_x2 = 0;
mytcp->th_off = sizeof(struct tcphdr) >> 2;
tcp_flags[0] = 0;
tcp_flags[1] = 1;
tcp_flags[2] = 0;
tcp_flags[3] = 0;
tcp_flags[4] = 0;
tcp_flags[5] = 0;
tcp_flags[6] = 0;
tcp_flags[7] = 0;
mytcp->th_flags = 0;
for (i=0; i<8; i++) {
mytcp->th_flags += (tcp_flags[i] << i);
}
mytcp->th_win = htons (65535);
mytcp->th_urp = htons (0);
mytcp->th_sum = tcp6_checksum (myip6, mytcp);
len = IP6_HDRLEN + sizeof(struct tcphdr);
for(i = 0; i < 10; i++) {
printf("This is the %d time to send the tcp packet----", i+1);
printf("from source address:%s--src_port:%d--->", src_ip, LOCAL_PORT);
printf("destination address:%s--des_port:%d\n", dst_ip, DES_PORT);
handle_tuple(TUPLE_ADD, IPVERSION, src_ip, dst_ip, LOCAL_PORT, DES_PORT, IPPROTO_TCP);
if (sendto(sock, sendpacket, len, 0, (struct sockaddr *) &server6addr, sizeof (struct sockaddr_in6)) <= 0) {
perror ("sendto() failed");
exit (EXIT_FAILURE);
}
timeo.tv_sec = TIMEOUT / 1000;
timeo.tv_usec = TIMEOUT % 1000;
while(0) {
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
maxfds = sock + 1;
n = select(maxfds, &readfds, NULL, NULL, &timeo);
if (n <= 0) {
printf("Error: select FD time out\n");
close(sock);
return;
}
memset(recvpacket, 0, sizeof(recvpacket));
unsigned int fromlen = sizeof(from);
n = recvfrom(sock, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)(&from), &fromlen);
if (n < 1)
break;
char from_ip[46];
inet_ntop(AF_INET6, &from.sin6_addr, from_ip, sizeof(from_ip));
printf("receive pkt from ip: %s, ",from_ip);
if (strcmp(from_ip, dst_ip) != 0) {
printf("expect ip:%s, ip wrong\n", dst_ip);
break;
}
from_ip6h = (struct ip6_hdr *)recvpacket;
from_tcp = (struct tcphdr *)(from_ip6h + 1);
if (from_tcp->th_sport == mytcp->th_dport && from_tcp->th_dport == mytcp->th_sport) {
printf("tcp response was received successfully!\n");
break;
} else {
printf("Error: failed to received tcp response!\n");
continue;
}
}
usleep(1000*500);
}
close(sock);
printf("-----------------------------\n");
}
void send_udp6(int sock, char *src, char * dst)
{
int len, datalen = 4;
int maxfds = 0;
int i, status, n;
fd_set readfds;
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
char src_ip[46] = {0};
char dst_ip[46] = {0};
uint8_t *data;
struct ip6_hdr *myip6, *from_ip6h;
struct udphdr *myudp, *from_udp;
struct sockaddr_in6 from;
struct sockaddr_in6 server6addr;
struct timeval timeo;
printf("-----------------------------\n");
strcpy (src_ip, src);
strcpy (dst_ip, dst);
printf("source address:%s\n", src_ip);
printf("destination address:%s\n", dst_ip);
bzero(&server6addr, sizeof(struct sockaddr_in6));
server6addr.sin6_family = AF_INET6;
server6addr.sin6_port = htons(0);
if (inet_pton(AF_INET6, dst_ip, &server6addr.sin6_addr) != 1) {
printf("wrong in inet_pthon \n");
exit(1);
}
bzero(sendpacket, sizeof(sendpacket));
myip6 = (struct ip6_hdr*)sendpacket;
myip6->ip6_flow = htonl ((6 << 28) | (0 << 20) | 0);
myip6->ip6_plen = htons (UDP_HDRLEN + datalen);
myip6->ip6_nxt = IPPROTO_UDP;
myip6->ip6_hops = 255;
if ((status = inet_pton (AF_INET6, src_ip, &(myip6->ip6_src))) != 1) {
fprintf (stderr, "inet_pton() failed.\nError message: %s", strerror (status));
exit (EXIT_FAILURE);
}
if ((status = inet_pton (AF_INET6, dst_ip, &(myip6->ip6_dst))) != 1) {
fprintf (stderr, "inet_pton() failed.\nError message: %s", strerror (status));
exit (EXIT_FAILURE);
}
myudp = (struct udphdr*)(sendpacket + sizeof(struct ip6_hdr));
myudp->source = htons(LOCAL_PORT);
printf("the sport is %d\n", LOCAL_PORT);
myudp->dest = htons(DES_PORT);
printf("the dport is %d\n", DES_PORT);
myudp->len = htons (UDP_HDRLEN + datalen);
data = (uint8_t*)(sendpacket + sizeof(struct ip6_hdr) + sizeof(struct udphdr));
memcpy(data, "Test", datalen);
myudp->check = udp6_checksum (myip6, myudp, data, datalen);
len = IP6_HDRLEN + UDP_HDRLEN + datalen;
for(i = 0; i < 10; i++) {
printf("This is the %d time to send the udp packet----",i+1);
printf("from source address:%s--src_port:%d--->",src_ip, LOCAL_PORT);
printf("destination address:%s--des_port:%d\n",dst_ip, DES_PORT);
handle_tuple(TUPLE_ADD, 6, src_ip, dst_ip, LOCAL_PORT, DES_PORT, IPPROTO_UDP);
if (sendto(sock, sendpacket, len, 0, (struct sockaddr *) &server6addr, sizeof (struct sockaddr_in6)) <= 0) {
perror ("sendto() failed");
exit (EXIT_FAILURE);
}
timeo.tv_sec = TIMEOUT / 1000;
timeo.tv_usec = TIMEOUT % 1000;
while(0) {
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
maxfds = sock + 1;
n = select(maxfds, &readfds, NULL, NULL, &timeo);
if (n <= 0) {
printf("Error: select FD time out\n");
close(sock);
return;
}
memset(recvpacket, 0, sizeof(recvpacket));
unsigned int fromlen = sizeof(from);
n = recvfrom(sock, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)(&from), &fromlen);
if (n < 1)
break;
char from_ip[46];
inet_ntop(AF_INET6, &from.sin6_addr, from_ip, sizeof(from_ip));
printf("receive pkt from ip: %s, ",from_ip);
if (strcmp(from_ip, dst_ip) != 0) {
printf("expect ip:%s, ip wrong\n", dst_ip);
break;
}
from_ip6h = (struct ip6_hdr *)recvpacket;
from_udp = (struct udphdr *)(from_ip6h + 1);
if (from_udp->source == myudp->dest && from_udp->dest == myudp->source) {
printf("udp response was received successfully!\n");
break;
} else {
printf("Error: failed to received udp response!\n");
continue;
}
}
usleep(1000*500);
}
close(sock);
printf("-----------------------------\n");
}
void send_icmpv6(int sock, char *src, char * dst)
{
int len, datalen = 4;
int nsent = 0;
int i, status, n, psdhdrlen;
int maxfds = 0;
fd_set readfds;
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
char psdhdr[PACKET_SIZE];
char src_ip[46] = {0};
char dst_ip[46] = {0};
char *data;
struct ip6_hdr *myip6, *from_ip6h;
struct icmp6_hdr *myicmp6, *from_icmp6;
struct sockaddr_in6 from;
struct sockaddr_in6 server6addr;
struct timeval timeo;
printf("-----------------------------\n");
strcpy (src_ip, src);
strcpy (dst_ip, dst);
printf("source address:%s\n", src_ip);
printf("destination address:%s\n", dst_ip);
bzero(&server6addr, sizeof(struct sockaddr_in6));
server6addr.sin6_family = AF_INET6;
server6addr.sin6_port = htons(0);
if (inet_pton(AF_INET6, dst_ip, &server6addr.sin6_addr) != 1) {
printf("wrong in inet_pthon \n");
exit(1);
}
bzero(sendpacket, sizeof(sendpacket));
myip6 = (struct ip6_hdr *)sendpacket;
myip6->ip6_flow = htonl ((6 << 28) | (0 << 20) | 0);
myip6->ip6_plen = htons(sizeof(struct icmp6_hdr) + datalen);
myip6->ip6_nxt = IPPROTO_ICMPV6;
myip6->ip6_hops = 255;
if ((status = inet_pton (AF_INET6, src_ip, &(myip6->ip6_src))) != 1) {
fprintf (stderr, "inet_pton() failed.\nError message: %s", strerror (status));
exit (EXIT_FAILURE);
}
if ((status = inet_pton (AF_INET6, dst_ip, &(myip6->ip6_dst))) != 1) {
fprintf (stderr, "inet_pton() failed.\nError message: %s", strerror (status));
exit (EXIT_FAILURE);
}
memcpy (psdhdr, myip6->ip6_src.s6_addr, 16); // Copy to checksum pseudo-header
memcpy (psdhdr + 16, myip6->ip6_dst.s6_addr, 16); // Copy to checksum pseudo-header
myicmp6 = (struct icmp6_hdr*)(sendpacket + sizeof(struct ip6_hdr));
myicmp6->icmp6_type = ICMP6_ECHO_REQUEST;
myicmp6->icmp6_code = 0;
myicmp6->icmp6_id = htons(getpid());
data = (char*)(sendpacket + sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr));
memcpy(data, "Test", datalen);
len = IP6_HDRLEN + sizeof(struct icmp6_hdr) + datalen;
// Need a pseudo-header for checksum calculation. Define length. (RFC 2460)
// Length = source IP (16 bytes) + destination IP (16 bytes)
// + upper layer packet length (4 bytes) + zero (3 bytes)
// + next header (1 byte)
psdhdrlen = 16 + 16 + 4 + 3 + 1 + sizeof(struct icmp6_hdr) + datalen;
for(i = 0; i < 10; i++) {
myicmp6->icmp6_seq = htons(nsent++);
myicmp6->icmp6_cksum = 0;
// Compute ICMPv6 checksum (RFC 2460).
// psdhdr[0 to 15] = source IPv6 address, set earlier.
// psdhdr[16 to 31] = destination IPv6 address, set earlier.
psdhdr[32] = 0; // Length should not be greater than 65535 (i.e., 2 bytes)
psdhdr[33] = 0; // Length should not be greater than 65535 (i.e., 2 bytes)
psdhdr[34] = (sizeof(struct icmp6_hdr) + datalen) / 256; // Upper layer packet length
psdhdr[35] = (sizeof(struct icmp6_hdr) + datalen) % 256; // Upper layer packet length
psdhdr[36] = 0; // Must be zero
psdhdr[37] = 0; // Must be zero
psdhdr[38] = 0; // Must be zero
psdhdr[39] = IPPROTO_ICMPV6;
memcpy (psdhdr + 40, myicmp6, sizeof(struct icmp6_hdr) + datalen);
myicmp6->icmp6_cksum = cal_chksum((uint16_t *)psdhdr, psdhdrlen);
printf("This is the %d time to send the icmpv6 packet----", i+1);
printf("from source address:%s--->", src_ip);
printf("destination address:%s\n", dst_ip);
handle_tuple(TUPLE_ADD, 6, src_ip, dst_ip,
myicmp6->icmp6_id, (myicmp6->icmp6_type << 8) | myicmp6->icmp6_code, IPPROTO_ICMPV6);
if(sendto(sock, sendpacket, len, 0, (struct sockaddr *) &server6addr, sizeof (struct sockaddr_in6)) <= 0)
{
perror ("sendto() failed");
exit (EXIT_FAILURE);
}
timeo.tv_sec = 10;
timeo.tv_usec = TIMEOUT % 1000;
while(0) {
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
maxfds = sock + 1;
n = select(maxfds, &readfds, NULL, NULL, &timeo);
if (n <= 0) {
printf("Error: select FD time out\n");
close(sock);
return;
}
memset(recvpacket, 0, sizeof(recvpacket));
unsigned int fromlen = sizeof(from);
n = recvfrom(sock, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)(&from), &fromlen);
printf("n: %d\r\n", n);
if (n < 1)
break;
char from_ip[46];
inet_ntop(AF_INET6, &from.sin6_addr, from_ip, sizeof(from_ip));
printf("receive pkt from ip: %s, ",from_ip);
if (strcmp(from_ip, dst_ip) != 0) {
printf("expect ip:%s, ip wrong\n", dst_ip);
continue;
}
from_ip6h = (struct ip6_hdr *)recvpacket;
from_icmp6 = (struct icmp6_hdr *)(from_ip6h + 1);
if ((from_icmp6->icmp6_type == 129) && from_icmp6->icmp6_id == htons(getpid())) {
printf("icmp echo reply was received successfully!\n");
break;
} else {
printf("Error: failed to received icmp echo reply! type: %d, id: %d, expect_id: %d\n",
from_icmp6->icmp6_type, from_icmp6->icmp6_id, getpid());
continue;
}
}
usleep(1000*500);
}
close(sock);
printf("-----------------------------\n");
}
void usage(char *name)
{
fprintf(stderr,"usage:%s [-v version][-s source_ip][-d destination_ip]"
"[-t net_type][-a source_port][-b destation_port]\n",name);
}