Spectre traffic generator v.0.9

This commit is contained in:
Alex Vanin 2016-05-06 20:53:19 +03:00
commit 8959cbc0d5
8 changed files with 849 additions and 0 deletions

10
Makefile Normal file
View file

@ -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)

57
headers/n_packet.h Normal file
View file

@ -0,0 +1,57 @@
#ifndef NPACK_H
#define NPACK_H
#include <stdint.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#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

35
headers/n_plan.h Normal file
View file

@ -0,0 +1,35 @@
#ifndef NPLAN_H
#define NPLAN_H
#include <stdio.h>
#include <n_packet.h>
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

26
headers/rand_exp.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef N_RANDEXP_H
#define N_RANDEXP_H
#include <gsl/gsl_rng.h>
#include <stdint.h>
#include <stdio.h>
#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

522
main.c Normal file
View file

@ -0,0 +1,522 @@
// Made by AlexVanin
#include "n_packet.h"
#include "n_plan.h"
#include "rand_exp.h"
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <malloc.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ether.h>
#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*)&eth_s[0], (unsigned int*)&eth_s[1], (unsigned int*)&eth_s[2],
(unsigned int*)&eth_s[3], (unsigned int*)&eth_s[4], (unsigned int*)&eth_s[5] ) )
{ eexit("Bad Source Mac Address\n") }
break;
case 'd':
if( 6 != sscanf( optarg, "%x:%x:%x:%x:%x:%x",
(unsigned int*)&eth_d[0], (unsigned int*)&eth_d[1], (unsigned int*)&eth_d[2],
(unsigned int*)&eth_d[3], (unsigned int*)&eth_d[4], (unsigned int*)&eth_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;
}

55
n_packet.c Normal file
View file

@ -0,0 +1,55 @@
#include "n_packet.h"
#include <malloc.h>
#include <string.h>
#include <netinet/ip.h>
#include <netinet/ether.h>
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));
}

58
n_plan.c Normal file
View file

@ -0,0 +1,58 @@
#include <malloc.h>
#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;
}

86
rand_exp.c Normal file
View file

@ -0,0 +1,86 @@
#include "rand_exp.h"
#include <gsl/gsl_randist.h>
#include <gsl/gsl_rng.h>
#include <sys/time.h>
#include <malloc.h>
#include <stdint.h>
#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;
}