Created
February 12, 2017 14:56
-
-
Save Chion82/699ae432a27507242ea788df324f4e47 to your computer and use it in GitHub Desktop.
fake TCP test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <arpa/inet.h> | |
#include <string.h> | |
#include "trans_packet.h" | |
void on_packet_recv(char* from_ip, uint16_t from_port, char* payload, int size, unsigned int seq) { | |
printf("Packet received from=%s:%d, seq=%d\n", from_ip, from_port, seq); | |
char* message = (char*)malloc(size); | |
memcpy(message, payload, size); | |
printf(message); | |
free(message); | |
printf("\n"); | |
} | |
int main (void) { | |
init_packet(); | |
struct packet_info packetinfo; | |
packetinfo.dest_ip = "108.0.0.1"; //填写服务器IP | |
packetinfo.dest_port = 8888; | |
packetinfo.source_ip = "192.168.1.100"; //本地IP | |
packetinfo.source_port = 34567; | |
packetinfo.on_packet_recv = on_packet_recv; | |
char* text = "Hello World!"; | |
send_packet(&packetinfo, text, strlen(text) + 1, 1234); | |
recv_packet_loop(&packetinfo); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <arpa/inet.h> | |
#include <string.h> | |
#include "trans_packet.h" | |
struct packet_info packetinfo; | |
void on_packet_recv(char* from_ip, uint16_t from_port, char* payload, int size, unsigned int seq) { | |
printf("Packet received from=%s:%d, seq=%d\n", from_ip, from_port, seq); | |
char* message = (char*)malloc(size); | |
memcpy(message, payload, size); | |
printf(message); | |
free(message); | |
printf("\n"); | |
packetinfo.dest_ip = from_ip; | |
packetinfo.dest_port = from_port; | |
char* text = "Response from server."; | |
send_packet(&packetinfo, text, strlen(text) + 1, 5678); | |
} | |
int main (void) { | |
init_packet(); | |
packetinfo.dest_ip = 0; | |
packetinfo.dest_port = 0; | |
packetinfo.source_ip = "108.0.0.1"; //填写服务器IP | |
packetinfo.source_port = 8888; | |
packetinfo.on_packet_recv = on_packet_recv; | |
recv_packet_loop(&packetinfo); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> //for printf | |
#include <string.h> //memset | |
#include <sys/socket.h> //for socket ofcourse | |
#include <stdlib.h> //for exit(0); | |
#include <errno.h> //For errno - the error number | |
#include <netinet/tcp.h> //Provides declarations for tcp header | |
#include <netinet/ip.h> //Provides declarations for ip header | |
#include <netinet/if_ether.h> | |
#include <arpa/inet.h> | |
#include "trans_packet.h" | |
/* | |
96 bit (12 bytes) pseudo header needed for tcp header checksum calculation | |
*/ | |
struct pseudo_header { | |
u_int32_t source_address; | |
u_int32_t dest_address; | |
u_int8_t placeholder; | |
u_int8_t protocol; | |
u_int16_t tcp_length; | |
}; | |
unsigned short csum(unsigned short *ptr,int nbytes); | |
int packet_send_sd; | |
int packet_recv_sd; | |
void init_packet() { | |
packet_send_sd = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); | |
packet_recv_sd = socket(AF_PACKET , SOCK_DGRAM , htons(ETH_P_ALL)); | |
if(packet_send_sd == -1 || packet_recv_sd == -1) { | |
//socket creation failed, may be because of non-root privileges | |
perror("Failed to create socket"); | |
exit(1); | |
} | |
//IP_HDRINCL to tell the kernel that headers are included in the packet | |
int one = 1; | |
const int *val = &one; | |
if (setsockopt (packet_send_sd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) { | |
perror("Error setting IP_HDRINCL"); | |
exit(2); | |
} | |
} | |
void recv_packet_loop(struct packet_info* packetinfo) { | |
int saddr_size , size; | |
struct sockaddr saddr; | |
unsigned short iphdrlen; | |
struct in_addr from_addr; | |
char buffer[MTU]; | |
while(1) { | |
saddr_size = sizeof(saddr); | |
//Receive a packet | |
size = recvfrom(packet_recv_sd, buffer, MTU, 0 ,&saddr , &saddr_size); | |
if(size <0 ) { | |
printf("Recvfrom error , failed to get packets\n"); | |
return; | |
} | |
//Now process the packet | |
struct iphdr *iph = (struct iphdr *)buffer; | |
iphdrlen =iph->ihl*4; | |
if (iph->protocol != IPPROTO_TCP) { | |
continue; | |
} | |
struct tcphdr *tcph=(struct tcphdr*)(buffer + iphdrlen); | |
if (ntohs(tcph->dest) != packetinfo->source_port) { | |
continue; | |
} | |
from_addr.s_addr = iph->saddr; | |
(*(packetinfo->on_packet_recv))(inet_ntoa(from_addr), ntohs(tcph->source), buffer + iphdrlen + tcph->doff*4, size - tcph->doff*4 - iphdrlen, tcph->seq); | |
} | |
} | |
int send_packet(struct packet_info* packetinfo, char* payload, int payloadlen, unsigned int seq) { | |
//Datagram to represent the packet | |
char datagram[MTU], *data , *pseudogram; | |
if (payloadlen > MTU - 40) { | |
return -1; | |
} | |
//zero out the packet buffer | |
memset (datagram, 0, MTU); | |
//IP header | |
struct iphdr *iph = (struct iphdr *) datagram; | |
//TCP header | |
struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip)); | |
struct sockaddr_in sin; | |
struct pseudo_header psh; | |
//Data part | |
data = datagram + sizeof(struct iphdr) + sizeof(struct tcphdr); | |
memcpy(data , payload, payloadlen); | |
//some address resolution | |
sin.sin_family = AF_INET; | |
sin.sin_port = htons(packetinfo->dest_port); | |
sin.sin_addr.s_addr = inet_addr (packetinfo->dest_ip); | |
//Fill in the IP Header | |
iph->ihl = 5; | |
iph->version = 4; | |
iph->tos = 0; | |
iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr) + payloadlen; | |
iph->id = htonl (54321); //Id of this packet | |
iph->frag_off = 0; | |
iph->ttl = 255; | |
iph->protocol = IPPROTO_TCP; | |
iph->check = 0; //Set to 0 before calculating checksum | |
iph->saddr = inet_addr(packetinfo->source_ip); //Spoof the source ip address | |
iph->daddr = sin.sin_addr.s_addr; | |
//TCP Header | |
tcph->source = htons(packetinfo->source_port); | |
tcph->dest = sin.sin_port; | |
tcph->seq = seq; | |
tcph->ack_seq = 0; | |
tcph->doff = 5; //tcp header size | |
tcph->fin=0; | |
tcph->syn=1; | |
tcph->rst=0; | |
tcph->psh=0; | |
tcph->ack=0; | |
tcph->urg=0; | |
tcph->window = htons (5840); /* maximum allowed window size */ | |
tcph->check = 0; //leave checksum 0 now, filled later by pseudo header | |
tcph->urg_ptr = 0; | |
//Now the TCP checksum | |
psh.source_address = inet_addr(packetinfo->source_ip); | |
psh.dest_address = sin.sin_addr.s_addr; | |
psh.placeholder = 0; | |
psh.protocol = IPPROTO_TCP; | |
psh.tcp_length = htons(sizeof(struct tcphdr) + payloadlen ); | |
int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + payloadlen; | |
pseudogram = malloc(psize); | |
memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header)); | |
memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr) + payloadlen); | |
tcph->check = csum( (unsigned short*) pseudogram , psize); | |
//Ip checksum | |
iph->check = csum ((unsigned short *) datagram, iph->tot_len); | |
free(pseudogram); | |
return sendto (packet_send_sd, datagram, iph->tot_len , 0, (struct sockaddr *) &sin, sizeof (sin)); | |
} | |
/* | |
Generic checksum calculation function | |
*/ | |
unsigned short csum(unsigned short *ptr,int nbytes) { | |
register long sum; | |
unsigned short oddbyte; | |
register short answer; | |
sum=0; | |
while(nbytes>1) { | |
sum+=*ptr++; | |
nbytes-=2; | |
} | |
if(nbytes==1) { | |
oddbyte=0; | |
*((u_char*)&oddbyte)=*(u_char*)ptr; | |
sum+=oddbyte; | |
} | |
sum = (sum>>16)+(sum & 0xffff); | |
sum = sum + (sum>>16); | |
answer=(short)~sum; | |
return(answer); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define MTU 1440 | |
struct packet_info { | |
char* dest_ip; | |
char* source_ip; | |
uint16_t dest_port; | |
uint16_t source_port; | |
void (*on_packet_recv)(char*, uint16_t, char*, int, unsigned int); | |
}; | |
void init_packet(); | |
int send_packet(struct packet_info* packetinfo, char* payload, int payloadlen, unsigned int seq); | |
void recv_packet_loop(struct packet_info* packetinfo); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment