| #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); |
| } |
| |
| |