commit 8959cbc0d536170f1d10df62fbf157bd24a2858a Author: AlexVanin Date: Fri May 6 20:53:19 2016 +0300 Spectre traffic generator v.0.9 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..da9ac9d --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +CC=gcc +IDIR=./headers +LIBS=-lgsl -lgslcblas -lm +LFLAGS=$(LIBS) -I$(IDIR) +CFLAGS=-Wall -static + +all: spectre + +spectre: main.c + $(CC) $(CFLAGS) *.c -o ./build/main $(LFLAGS) diff --git a/headers/n_packet.h b/headers/n_packet.h new file mode 100644 index 0000000..4946c4d --- /dev/null +++ b/headers/n_packet.h @@ -0,0 +1,57 @@ +#ifndef NPACK_H +#define NPACK_H + +#include +#include +#include + +#define DEFAULT_INTERFACE "enp0s3" + +#define MY_DEST_MAC0 0x01 +#define MY_DEST_MAC1 0x01 +#define MY_DEST_MAC2 0x01 +#define MY_DEST_MAC3 0x01 +#define MY_DEST_MAC4 0x01 +#define MY_DEST_MAC5 0x01 + +#define MY_DEST_IP "192.168.0.111" +#define MY_SRC_PORT 2134 +#define MY_DEST_PORT 3456 +#define MY_SEQ_NUMBER 4253 + +#define BUF_SIZ 2048 + +struct sockaddr_ll +{ + unsigned short sll_family; + unsigned short sll_protocol; + int sll_ifindex; + unsigned short sll_hatype; + unsigned char sll_pkttype; + unsigned char sll_halen; + unsigned char sll_addr[8]; +}; + +struct pseudo_hdr +{ + uint32_t saddr; + uint32_t daddr; + uint8_t zeros; + uint8_t protocol; + uint16_t tot_len; +}; + +typedef enum +{ + TCP = IPPROTO_TCP, + UDP = IPPROTO_UDP +} protocol; + +unsigned short s_csum(unsigned short*, int); +unsigned short l_csum(struct iphdr*, void*, int); +uint16_t calc_ip_size(uint16_t); +uint16_t calc_ip_csum(char*); +uint16_t calc_udp_size(uint16_t); +uint16_t calc_tr_csum(char*, uint16_t); + +#endif diff --git a/headers/n_plan.h b/headers/n_plan.h new file mode 100644 index 0000000..4429810 --- /dev/null +++ b/headers/n_plan.h @@ -0,0 +1,35 @@ +#ifndef NPLAN_H +#define NPLAN_H + +#include +#include + +typedef struct +{ + uint16_t p_size; + uint32_t p_delay; +} t_metaunit; + +typedef struct +{ + char* p_buf; + uint16_t p_size; + protocol p_proto; + uint16_t p_ip_size; + uint16_t p_ip_csum; + uint16_t p_tr_size; + uint16_t p_tr_csum; +} t_dataunit; + +typedef struct +{ + t_dataunit d_unit; + uint32_t time; +} t_planunit; + + + +t_metaunit* cr_meta(uint32_t, uint16_t, uint16_t, double, uint32_t, uint32_t, double, FILE*, FILE*); +int destroy_meta(t_metaunit*); + +#endif diff --git a/headers/rand_exp.h b/headers/rand_exp.h new file mode 100644 index 0000000..c4dc56a --- /dev/null +++ b/headers/rand_exp.h @@ -0,0 +1,26 @@ +#ifndef N_RANDEXP_H +#define N_RANDEXP_H + +#include +#include +#include + +#define EXPONEN_D 1 +#define FLAT_D 2 +#define CUSTOM_D 3 + +typedef struct +{ + uint16_t rows; + double* data; +} cd_unit; + +int creat_cd_unit(FILE*, cd_unit*); +int destroy_cd_unit(cd_unit*); + +gsl_rng* init_exp_d(); +int destroy_exp_d(gsl_rng*); +uint32_t get_exp(gsl_rng*, double, uint32_t, uint32_t); +uint32_t get_custom(gsl_rng*, uint32_t, uint32_t, cd_unit*); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..252d0b3 --- /dev/null +++ b/main.c @@ -0,0 +1,522 @@ +// Made by AlexVanin + +#include "n_packet.h" +#include "n_plan.h" +#include "rand_exp.h" + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define eexit(text) printf((text)); exit(1); + +const unsigned long long nano = 1000000000; + +char* init_packet(int sockfd, char* if_name, char* ip_s, uint16_t port_s, char* ip_d, uint16_t port_d, protocol p_proto, + uint8_t eth_s[6], uint8_t eth_d[6], struct sockaddr_ll * sockaddr, uint16_t* h_size) +{ + struct ifreq if_idx; + struct ifreq if_mac; + struct ifreq if_ip; + + struct ether_header *eh; + struct iphdr *iph; + struct udphdr *udph; + struct tcphdr *tcph; + + uint16_t tx_len = 0; + + char* p_buf = malloc(BUF_SIZ); + + eh = (struct ether_header *) p_buf; + iph = (struct iphdr *) (p_buf + sizeof(struct ether_header)); + udph = (struct udphdr *) (p_buf + sizeof(struct iphdr) + sizeof(struct ether_header)); + tcph = (struct tcphdr *) (p_buf + sizeof(struct iphdr) + sizeof(struct ether_header)); + + /* Get the index of the interface to send on */ + memset(&if_idx, 0, sizeof(struct ifreq)); + strncpy(if_idx.ifr_name, if_name, IFNAMSIZ-1); + if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) { + perror("SIOCGIFINDEX"); + exit(1); + } + /* Get the MAC address of the interface to send on */ + memset(&if_mac, 0, sizeof(struct ifreq)); + strncpy(if_mac.ifr_name, if_name, IFNAMSIZ-1); + if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0) { + perror("SIOCGIFHWADDR"); + exit(1); + } + + /* Get the IP address of the interface to send on */ + memset(&if_ip, 0, sizeof(struct ifreq)); + strncpy(if_ip.ifr_name, if_name, IFNAMSIZ-1); + if (ioctl(sockfd, SIOCGIFADDR, &if_ip) < 0) { + perror("SIOCGIFADDR"); + exit(1); + } + + /* Construct the Ethernet header */ + //memset(sendbuf, 0, BUF_SIZ); + if (eth_s == NULL) { + eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0]; + eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1]; + eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2]; + eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3]; + eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4]; + eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5]; + } + else { + eh->ether_shost[0] = eth_s[0]; + eh->ether_shost[1] = eth_s[1]; + eh->ether_shost[2] = eth_s[2]; + eh->ether_shost[3] = eth_s[3]; + eh->ether_shost[4] = eth_s[4]; + eh->ether_shost[5] = eth_s[5]; + } + if (eth_d == NULL) { + eh->ether_dhost[0] = MY_DEST_MAC0; + eh->ether_dhost[1] = MY_DEST_MAC1; + eh->ether_dhost[2] = MY_DEST_MAC2; + eh->ether_dhost[3] = MY_DEST_MAC3; + eh->ether_dhost[4] = MY_DEST_MAC4; + eh->ether_dhost[5] = MY_DEST_MAC5; + } + else { + eh->ether_dhost[0] = eth_d[0]; + eh->ether_dhost[1] = eth_d[1]; + eh->ether_dhost[2] = eth_d[2]; + eh->ether_dhost[3] = eth_d[3]; + eh->ether_dhost[4] = eth_d[4]; + eh->ether_dhost[5] = eth_d[5]; + } + eh->ether_type = htons(ETH_P_IP); + tx_len += sizeof(struct ether_header); + + iph->ihl = 5; + iph->version = 4; + iph->tos = 16; // Low delay + iph->id = htons(54321); + iph->ttl = IPDEFTTL; // hops + + iph->protocol = p_proto; + + if (ip_s == NULL) iph->saddr = inet_addr(inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr)); + else { + iph->saddr = inet_addr(ip_s); + if (iph->saddr == -1) { + eexit("Cannot parse ipS\n"); + } + } + + if (ip_d == NULL) iph->daddr = inet_addr(MY_DEST_IP); + else { + iph->daddr = inet_addr(ip_d); + if (iph->daddr == -1) { + eexit("Cannot parse ipD\n"); + } + } + + tx_len += sizeof(struct iphdr); + + if (p_proto == UDP) { + if (port_s == 0) udph->source = htons(MY_SRC_PORT); + else udph->source = htons(port_s); + + if (port_d == 0) udph->dest = htons(MY_DEST_PORT); + else udph->dest = htons(port_d); + + udph->check = 0; + tx_len += sizeof(struct udphdr); + } + else if (p_proto == TCP) { + if (port_s == 0) + tcph->source = htons(MY_SRC_PORT); + else + tcph->source = htons(port_s); + if (port_d == 0) + tcph->dest = htons(MY_DEST_PORT); + else + tcph->dest = htons(port_d); + + tcph->seq = htons(MY_SEQ_NUMBER); // inital sequence number + tcph->ack_seq = htons(0); // acknowledgement number + tcph->ack = 0; // acknowledgement flag + tcph->syn = 1; // synchronize flag + tcph->rst = 0; // reset flag + tcph->psh = 0; // push flag + tcph->fin = 0; // finish flag + tcph->urg = 0; // urgent flag + tcph->check = 0; // tcp checksum + tcph->doff = 5; // data offset + tcph->res1 = 0; + tcph->res2 = 0; + + tx_len += sizeof(struct tcphdr); + } + + /* Index of the network device */ + sockaddr->sll_ifindex = if_idx.ifr_ifindex; + /* Address length*/ + sockaddr->sll_halen = ETH_ALEN; + /* Destination MAC */ + sockaddr->sll_addr[0] = MY_DEST_MAC0; + sockaddr->sll_addr[1] = MY_DEST_MAC1; + sockaddr->sll_addr[2] = MY_DEST_MAC2; + sockaddr->sll_addr[3] = MY_DEST_MAC3; + sockaddr->sll_addr[4] = MY_DEST_MAC4; + sockaddr->sll_addr[5] = MY_DEST_MAC5; + + *h_size = tx_len; + return p_buf; +} + +int destroy_packet(char* buf) +{ + free( buf ); + return 0; +} + + + +int fill_dataunit(t_dataunit* d_unit, char* p_buf, uint16_t h_size, uint16_t p_size, protocol p_proto) +{ + struct iphdr *iph = (struct iphdr *) (p_buf + sizeof(struct ether_header)); + struct udphdr *udph = (struct udphdr *) (p_buf + sizeof(struct ether_header)+sizeof(struct iphdr)); + + if (h_size > p_size) { eexit("Header size is more than packet size, plaese specify right params\n") } + d_unit->p_size = p_size; + + d_unit->p_buf = p_buf; + d_unit->p_proto = p_proto; + + d_unit->p_ip_size = calc_ip_size(p_size); + iph->tot_len = htons(d_unit->p_ip_size); + d_unit->p_ip_csum = calc_ip_csum(p_buf); + + if (p_proto == UDP) + { + d_unit->p_tr_size = calc_udp_size(p_size); + udph->len = htons(d_unit->p_tr_size); + d_unit->p_tr_csum = calc_tr_csum(p_buf, p_size); + } + else if (p_proto == TCP) + { + d_unit->p_tr_csum = calc_tr_csum(p_buf, p_size); + } + return 0; +} + +int extract_dataunit(t_dataunit* d_unit) +{ + struct iphdr *iph = (struct iphdr*)(d_unit->p_buf + sizeof(struct ether_header)); + struct udphdr *udph = (struct udphdr*)(d_unit->p_buf + sizeof(struct ether_header)+sizeof(struct iphdr)); + struct tcphdr *tcph = (struct tcphdr*)(d_unit->p_buf + sizeof(struct ether_header)+sizeof(struct iphdr)); + + iph->tot_len = htons(d_unit->p_ip_size); + iph->check = d_unit->p_ip_csum; + + if (d_unit->p_proto == UDP) { + udph->len = htons(d_unit->p_tr_size); + udph->check = d_unit->p_tr_csum; + } + else { + tcph->check = d_unit->p_tr_csum; + } + + return 0; +} + + +t_planunit* creat_plan(char* p_buf, uint16_t h_size, t_metaunit* m_plan, uint32_t p_cnt, protocol p_proto) +{ + t_planunit* plan = malloc(sizeof(t_planunit) * p_cnt); + for (int i = 0; i < p_cnt; i++) { + plan[i].time = m_plan[i].p_delay; + fill_dataunit(&(plan[i].d_unit), p_buf, h_size, m_plan[i].p_size, p_proto); + } + return plan; +} + + +int exec_plan(t_planunit* plan, uint32_t p_cnt, int sockfd, struct sockaddr_ll* sockaddr) +{ + struct timespec tm; + uint64_t t1, t2; + t1 = 0; t2 = 0; + int64_t t3; + + for (int i = 0; i < p_cnt; i++) { + extract_dataunit(&(plan[i].d_unit)); + if (i != 0) { + clock_gettime( CLOCK_REALTIME, &tm ); + t1 = tm.tv_nsec + tm.tv_sec * nano; + t3 = (int64_t)(plan[i-1].time) - (int64_t)((t1 - t2)/1000); + if (t3 - 700 > 0) //Magic Number 600 + usleep(t3-700); + } + if (sendto(sockfd, plan[i].d_unit.p_buf, plan[i].d_unit.p_size, 0, (struct sockaddr*)sockaddr, sizeof(struct sockaddr_ll)) < 0) + printf("Send failed\n"); + clock_gettime( CLOCK_REALTIME, &tm ); + t2 = tm.tv_nsec + tm.tv_sec * nano; + } + return 0; +} + +int destroy_plan(t_planunit* plan) +{ + free( plan ); + return 0; +} + +int main (int argc, char* argv[]) +{ + int sockfd; + uint16_t h_size; + struct sockaddr_ll sockaddr; + t_metaunit* m_plan; + t_planunit* plan; + char* p_buff; + + static protocol p_proto = 0; + static int distribution = 0; + static char my_eth = 1; + + char* if_name = NULL; + uint32_t p_cnt = 0; + + uint8_t eth_s[6]; + uint8_t eth_d[6] = { MY_DEST_MAC0, MY_DEST_MAC1, MY_DEST_MAC2, + MY_DEST_MAC3, MY_DEST_MAC4, MY_DEST_MAC5}; + + char *ip_s = NULL; + char *ip_d = NULL; + uint16_t port_s = 0; + uint32_t port_d = 0; + char* t_file_n = NULL; + char* s_file_n = NULL; + FILE* t_file = NULL; + FILE* s_file = NULL; + + uint16_t s_a = 0, s_b = 0; + uint32_t t_a = 0, t_b = 0; + double s_mu = 0.0, t_mu = 0.0; + + + int c; + while ( 1 ) + { + static struct option long_options[] = + { + {"UDP", no_argument, (void*)&p_proto, UDP}, + {"TCP", no_argument, (void*)&p_proto, TCP}, + {"exponential", no_argument, (void*)&distribution, EXPONEN_D}, + {"flat", no_argument, (void*)&distribution, FLAT_D}, + {"custom", no_argument, (void*)&distribution, CUSTOM_D}, + {"iface", required_argument, 0, 'a'}, + {"count", required_argument, 0, 'b'}, + {"ethS", required_argument, 0, 'c'}, + {"ethD", required_argument, 0, 'd'}, + {"ipS", required_argument, 0, 'e'}, + {"ipD", required_argument, 0, 'f'}, + {"portS", required_argument, 0, 'g'}, + {"portD", required_argument, 0, 'h'}, + {"minT", required_argument, 0, 'i'}, + {"maxT", required_argument, 0, 'j'}, + {"avgT", required_argument, 0, 'k'}, + {"minS", required_argument, 0, 'l'}, + {"maxS", required_argument, 0, 'm'}, + {"avgS", required_argument, 0, 'n'}, + {"fileT", required_argument, 0, 'o'}, + {"fileS", required_argument, 0, 'p'}, + {0, 0, 0, 0} + }; + int option_index = 0; + c = getopt_long_only(argc, argv, "", long_options, &option_index); + if (c == -1) + break; + switch (c) + { + case 0: + break; + case 'a': + if_name = optarg; + break; + case 'b': + p_cnt = atoi(optarg); + if (!p_cnt) { eexit("Bad Package Count\n") } + break; + case 'c': + my_eth = 0; + if( 6 != sscanf( optarg, "%x:%x:%x:%x:%x:%x", + (unsigned int*)ð_s[0], (unsigned int*)ð_s[1], (unsigned int*)ð_s[2], + (unsigned int*)ð_s[3], (unsigned int*)ð_s[4], (unsigned int*)ð_s[5] ) ) + { eexit("Bad Source Mac Address\n") } + break; + case 'd': + if( 6 != sscanf( optarg, "%x:%x:%x:%x:%x:%x", + (unsigned int*)ð_d[0], (unsigned int*)ð_d[1], (unsigned int*)ð_d[2], + (unsigned int*)ð_d[3], (unsigned int*)ð_d[4], (unsigned int*)ð_d[5] ) ) + { eexit("Bad Destination Mac Address\n") } + break; + case 'e': + ip_s = optarg; + break; + case 'f': + ip_d = optarg; + break; + case 'g': + if (atoi(optarg) > 65535 || atoi(optarg) <= 0) + { eexit("Bad Source Port\n") } + else port_s = atoi(optarg); + break; + case 'h': + if (atoi(optarg) > 65535 || atoi(optarg) <= 0) + { eexit("Bad Destination Port\n") } + else port_d = atoi(optarg); + break; + case 'i': + t_a = atoi(optarg) * 1000; + break; + case 'j': + t_b = atoi(optarg) * 1000; + break; + case 'k': + t_mu = atof(optarg) * 1000; + break; + case 'l': + s_a = atoi(optarg); + break; + case 'm': + s_b = atoi(optarg); + break; + case 'n': + s_mu = atof(optarg); + break; + case 'o': + t_file_n = optarg; + break; + case 'p': + s_file_n = optarg; + break; + default: + break; + } + } + + if (p_proto == 0) { eexit("Protocol not specified\n") } + if (distribution == 0) { eexit("Distribution not specified\n") } + if (if_name == NULL) { eexit("No interface specified\n") } + if (p_cnt == 0) { eexit("No package to send\n") } + if ((ip_s == NULL) || (ip_d == NULL)) { eexit("IP-adresses not specified\n") } + + if (distribution == FLAT_D) { + if ( (t_mu != 0.0) && (t_a == 0) && (t_b == 0) && (t_file_n == NULL) ) { + t_a = (uint32_t)t_mu; + t_mu = 0.0; + } + else { eexit("Wrong time paramaters combination for flat distribution\n") } + + if ( (s_mu != 0.0) && (s_a == 0) && (s_b == 0) && (s_file_n == NULL) ) { + s_a = (uint32_t)s_mu; + s_mu = 0.0; + } + else { eexit("Wrong size paramaters combination for flat distribution\n") } + } + else if (distribution == EXPONEN_D) { + if ( (t_mu != 0.0) && (t_a == 0) && (t_b == 0) && (t_file_n == NULL) ) { + t_a = (uint32_t)t_mu; + t_mu = 0.0; + } + else if ( (t_mu != 0.0) && (t_a != 0) && (t_b != 0) && (t_file_n == NULL) ) { + if (t_a >= t_b) { eexit("Wrong time params\n") } + if (((uint32_t)t_mu <= t_a) || ((uint32_t)t_mu >= t_b)) + { eexit("Wrong avg time\n") } + } + else { eexit("Wrong time paramaters combination for exponential distribution\n") } + + if ( (s_mu != 0.0) && (s_a == 0) && (s_b == 0) && (s_file_n == NULL) ) { + s_a = (uint32_t)s_mu; + s_mu = 0.0; + } + else if ( (s_mu != 0.0) && (s_a != 0) && (s_b != 0) && (s_file_n == NULL) ) { + if (s_a >= s_b) { eexit("Wrong time params\n") } + if (((uint32_t)s_mu <= s_a) || ((uint32_t)s_mu >= s_b)) + { eexit("Wrong avg time\n") } + } + else { eexit("Wrong size paramaters combination for exponential distribution\n") } + } + else if (distribution == CUSTOM_D) { + if ( (t_mu != 0.0) && (t_a == 0) && (t_b == 0) && (t_file_n == NULL) ) { + t_a = (uint32_t)t_mu; + t_mu = 0.0; + } + else if ( (t_mu != 0.0) && (t_a != 0) && (t_b != 0) && (t_file_n == NULL) ) { + if (t_a >= t_b) { eexit("Wrong time params\n") } + if (((uint32_t)t_mu <= t_a) || ((uint32_t)t_mu >= t_b)) + { eexit("Wrong avg time\n") } + } + else if ( (t_mu == 0.0) && (t_a != 0) && (t_b != 0) && (t_file_n != NULL) ) { + if (t_a >= t_b) { eexit("Wrong time params\n") } + } + else { eexit("Wrong time paramaters combination for custom distribution\n") } + + if ( (s_mu != 0.0) && (s_a == 0) && (s_b == 0) && (s_file_n == NULL) ) { + s_a = (uint32_t)s_mu; + s_mu = 0.0; + } + else if ( (s_mu != 0.0) && (s_a != 0) && (s_b != 0) && (s_file_n == NULL) ) { + if (s_a >= s_b) { eexit("Wrong time params\n") } + if (((uint32_t)s_mu <= s_a) || ((uint32_t)s_mu >= s_b)) + { eexit("Wrong avg time\n") } + } + else if ( (s_mu == 0.0) && (s_a != 0) && (s_b != 0) && (s_file_n != NULL) ) { + if (s_a >= s_b) { eexit("Wrong time params\n") } + } + else { eexit("Wrong size paramaters combination for custom distribution\n") } + } + + if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) { + perror("Cannot create Socket\n"); + exit(1); + } + + if (t_file_n != NULL) t_file = fopen(t_file_n, "r"); + if (s_file_n != NULL) s_file = fopen(s_file_n, "r"); + + + if (my_eth) p_buff = init_packet(sockfd, if_name, ip_s, port_s, ip_d, port_d, p_proto, NULL, eth_d, &sockaddr, &h_size); + else p_buff = init_packet(sockfd, if_name, ip_s, port_s, ip_d, port_d, p_proto, eth_s, eth_d, &sockaddr, &h_size); + + m_plan = cr_meta(p_cnt, s_a, s_b, s_mu, t_a, t_b, t_mu, s_file, t_file); + plan = creat_plan(p_buff, h_size, m_plan, p_cnt, p_proto); +/* for (int i = 0; i < p_cnt; i++) + { + printf("%d\n",plan[i].d_unit.p_size); + } + return 0; */ + exec_plan(plan, p_cnt, sockfd, &sockaddr); + + destroy_meta(m_plan); + destroy_plan(plan); + + if (t_file != NULL) fclose(t_file); + if (s_file != NULL) fclose(s_file); + return 0; + +} diff --git a/n_packet.c b/n_packet.c new file mode 100644 index 0000000..3224274 --- /dev/null +++ b/n_packet.c @@ -0,0 +1,55 @@ +#include "n_packet.h" + +#include +#include +#include +#include + +unsigned short s_csum(unsigned short *buf, int nwords) +{ + unsigned long sum; + for(sum=0; nwords>0; nwords--) + sum += *buf++; + sum = (sum >> 16) + (sum &0xffff); + sum += (sum >> 16); + return (unsigned short)(~sum); +} + +unsigned short l_csum(struct iphdr* iph, void* buf, int buflen) +{ + char data[4096]; + struct pseudo_hdr *phdr = (struct pseudo_hdr *)data; + + phdr->saddr = iph->saddr; + phdr->daddr = iph->daddr; + phdr->zeros = 0; + phdr->protocol = iph->protocol; + phdr->tot_len = htons(buflen); + + memcpy(data+sizeof(struct pseudo_hdr), buf, buflen); + + return s_csum((unsigned short*)data, (buflen+sizeof(struct pseudo_hdr))/2); +} + +uint16_t calc_ip_size(uint16_t p_size) +{ + return p_size - sizeof(struct ether_header); +} + +uint16_t calc_ip_csum(char* p_buf) +{ + return s_csum((unsigned short *)(p_buf+sizeof(struct ether_header)), sizeof(struct iphdr)/2); +} + +uint16_t calc_udp_size(uint16_t p_size) +{ + return p_size - sizeof(struct ether_header) - sizeof(struct iphdr); +} + +uint16_t calc_tr_csum(char* p_buf, uint16_t p_size) +{ + struct iphdr *iph = (struct iphdr *) (p_buf + sizeof(struct ether_header)); + + return l_csum(iph, p_buf+sizeof(struct ether_header)+sizeof(struct iphdr), + p_size - sizeof(struct ether_header) - sizeof(struct iphdr)); +} diff --git a/n_plan.c b/n_plan.c new file mode 100644 index 0000000..459175f --- /dev/null +++ b/n_plan.c @@ -0,0 +1,58 @@ +#include +#include "n_plan.h" +#include "rand_exp.h" + +t_metaunit* cr_meta(uint32_t p_cnt, uint16_t s_a, uint16_t s_b, double s_mu, + uint32_t t_a, uint32_t t_b, double t_mu, FILE* s_file, FILE* t_file) +{ + int i; + t_metaunit* m_plan; + gsl_rng *gr1, *gr2; + + cd_unit t_unit; + cd_unit s_unit; + + if ((t_a == 0) ^ (s_a == 0)) { + return NULL; + } + + if (s_file != NULL) creat_cd_unit(s_file, &s_unit); + if (t_file != NULL) creat_cd_unit(t_file, &t_unit); + + + gr1 = init_exp_d(); + m_plan = malloc(sizeof(t_metaunit) * p_cnt); + gr2 = init_exp_d(); + + for (i = 0; i < p_cnt; i++) { + if (t_file != NULL) { + m_plan[i].p_delay = get_custom(gr1, t_a, t_b, &t_unit); + } + else { + if (t_b == 0) m_plan[i].p_delay = t_a; + else m_plan[i].p_delay = get_exp(gr1, t_mu, t_a, t_b); + } + + if (s_file != NULL) { + m_plan[i].p_size = get_custom(gr2, s_a, s_b, &s_unit); + } + else { + if (s_b == 0) m_plan[i].p_size = s_a; + else m_plan[i].p_size = get_exp(gr2, s_mu, s_a, s_b); + } + } + + if (t_file != NULL) destroy_cd_unit(&t_unit); + if (s_file != NULL) destroy_cd_unit(&s_unit); + + destroy_exp_d(gr1); + destroy_exp_d(gr2); + + return m_plan; +} + +int destroy_meta(t_metaunit* m_plan) +{ + free( m_plan ); + return 0; +} diff --git a/rand_exp.c b/rand_exp.c new file mode 100644 index 0000000..2754ea4 --- /dev/null +++ b/rand_exp.c @@ -0,0 +1,86 @@ +#include "rand_exp.h" + +#include +#include +#include +#include +#include + +#define eexit(text) printf((text)); exit(1); + +double r_max = -1; +double r_min = 10000; +double mu = 0; + + +int creat_cd_unit(FILE* file, cd_unit* unit) +{ + double summ = 0; + double temp = 0; + char string[100]; + if (fgets(string, 100, file) != NULL) + { + if ( 1 != sscanf(string, "%d", (int*)&(unit->rows)) ) + { eexit("Cannot read file\n") } + } + unit->data = malloc(sizeof(double) * unit->rows); + + for (int i = 0; i < unit->rows; i++) { + fgets(string,100,file); + if ( 1 != sscanf(string, "%lf", &temp) ) + { eexit("Cannot read file\n") } + unit->data[i] = summ; + summ += temp; + if (summ > 1.0) { eexit("Wrong distribution file containg\n") } + } + return 0; +} + +int destroy_cd_unit(cd_unit* unit) +{ + free(unit->data); + return 0; +} + +gsl_rng* init_exp_d() +{ + struct timeval t1; + const gsl_rng_type* T; + gsl_rng* gr = malloc( sizeof( gsl_rng ) ); + + T = gsl_rng_default; + gr = gsl_rng_alloc( T ); + + gettimeofday( &t1, NULL ); + gsl_rng_set( gr, t1.tv_usec * t1.tv_sec ); + + return gr; +} + +uint32_t get_exp(gsl_rng* gr, double mu, uint32_t a, uint32_t b) +{ + double res = a + gsl_ran_exponential( gr, mu - a ); + if ( res > b ) res = gsl_ran_flat( gr, a, b ); + return (uint32_t)res; +} + + +int destroy_exp_d(gsl_rng* gr) +{ + gsl_rng_free( gr ); //Free allocated memory for generator + return 0; +} + +uint32_t get_custom(gsl_rng* gr, uint32_t a, uint32_t b, cd_unit* cd) +{ + int i = 0; + uint32_t dif = (b-a) / cd->rows; + double rand = gsl_rng_uniform(gr); + + for (i = 1; i < cd->rows; i++) { + if (rand < cd->data[i]) + break; + } + uint32_t inner = gsl_rng_uniform_int(gr, dif+1); + return a+(i-1)*dif+inner; +}