Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C程序冻结;futex等一下排队等我_C_Sockets_Network Programming_Freeze_Futex - Fatal编程技术网

C程序冻结;futex等一下排队等我

C程序冻结;futex等一下排队等我,c,sockets,network-programming,freeze,futex,C,Sockets,Network Programming,Freeze,Futex,我已经按照要求完整地包含了代码,以便您可以对其进行测试。请记住,这还远未完成,但应该能够通过稳定的tcp连接发送和接收数据包 当我运行它时,我得到: ./bunny -i 84.49.76.98 -p 80 -o 79.161.200.48 -t 80 Raw packet reader created Waiting 1 second for packet reader thread to settle down... socket() - Using SOCK_RAW and TCP p

我已经按照要求完整地包含了代码,以便您可以对其进行测试。请记住,这还远未完成,但应该能够通过稳定的tcp连接发送和接收数据包

当我运行它时,我得到:

./bunny -i 84.49.76.98 -p 80 -o 79.161.200.48 -t 80

Raw packet reader created
Waiting 1 second for packet reader thread to settle down...

socket() - Using SOCK_RAW and TCP protocol is OK.
Socketoptions OK.
然后它就挂了。我还使用了strace,这给了我(只包括它停止的最后一点):

系统监视器显示程序正在休眠,并给我futex_wait_queue_

这可能是因为某个地方的内存泄漏导致对futex的调用过多吗

#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <pcap.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

#define VERSION "1.0"
#define PCKT_LEN 8192

/* Prototypes */    
int sock;   
void run();
void capture();
void usage(); 
in_addr_t sip;
in_addr_t dip;
char *dstip = 0;
int s_seq;
int sport;
int dport;              

struct pseudo {
struct in_addr sourceip;
struct in_addr destip;
unsigned char placeholder;
unsigned char protocol;
unsigned char tcp_len;
struct tcphdr tcp;
};

struct ipheader {

unsigned char       iph_ihl:5, 
                    iph_ver:4;
unsigned char       iph_tos;
unsigned short int  iph_len;
unsigned short int  iph_id;
unsigned char       iph_flags;
unsigned short int  iph_offset;
unsigned char       iph_ttl;
unsigned char       iph_protocol;
unsigned short int  iph_chksum;
unsigned int        iph_sourceip;
unsigned int        iph_destip;
};

struct tcpheader {
unsigned short int  tcph_sourceport;
unsigned short int  tcph_destport;
unsigned int        tcph_seqnum;
unsigned int        tcph_acknum;
unsigned char       tcph_reserved:4, tcph_offset:4;
unsigned char       tcph_flags;
unsigned short int  tcph_win;
unsigned short int  tcph_chksum;
unsigned short int  tcph_urgptr;
};



/* Checksum */
unsigned short checksum (unsigned short *pac, int len)
{ 
unsigned long sum;
for (sum = 0; len > 0; len--)
    sum += *pac++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return(~sum);
}               

/* Checksum TCP */
unsigned short checksum_tcp (unsigned short len, unsigned short sourceip[], 
                            unsigned short destip[], unsigned short buf[])
{
unsigned char protocol = 6;
unsigned long sum;
int nleft;
unsigned short *w;

sum = 0;
nleft = len;
w=buf;

while(nleft > 1)
    {
        sum += *w++;
        nleft -= 2;
    }
if(nleft > 0)
    {
        sum += *w&ntohs(0xFF00);
    }

sum += sourceip[0];
sum += sourceip[1];
sum += destip[0];
sum += destip[1];
sum += htons(len);
sum += htons(protocol);

sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);

sum = ~sum;
return ((unsigned short) sum);
}

int main(int argc,char **argv)
{
int c;

/* Are we in root? */   
if(geteuid() !=0)
    {
        printf("Root access is required to run this program.\n\n");
        exit(0);        
    }   

while (1)
    {
        static struct option long_options[] =
            {
                /* Options */
            {"send",       no_argument,       0, 's'}, /* args s, r and f have no function yet */
            {"receive",    no_argument,       0, 'r'},
            {"file",       required_argument, 0, 'f'}, 
            {"destip",     required_argument, 0, 'i'},
            {"destport",   required_argument, 0, 'p'},
            {"sourceip",   required_argument, 0, 'o'},
            {"sourceport", required_argument, 0, 't'},
            {0, 0, 0, 0}
            };

           int option_index = 0;

           c = getopt_long (argc, argv, "srf:d:i:p:o:t:",
                        long_options, &option_index);

                      /* Detect the end of the options. */
            if (c == -1)
                break;

            switch (c)
                {
                    case 0: /* If this option set a flag, do nothing else now. */
                            if (long_options[option_index].flag != 0)
                            break;
                                printf ("option %s", long_options[option_index].name);
                            if (optarg)
                                printf (" with arg %s", optarg);
                                printf ("\n");
                            break;

                    case 's': puts ("option -s\n");
                              break;
                    case 'r': puts ("option -r\n");
                              break;
                    case 'f': printf ("option -f with value `%s'\n", optarg);
                              break;
                    case 'i': dip = inet_addr(optarg);
                              dstip = optarg;
                              break;
                    case 'p': dport = htons(atoi(optarg)); 
                              /* Add handling of bad/non number input here */
                              break;
                    case 'o': sip = inet_addr(optarg);
                              break;
                    case 't': sport = htons(atoi(optarg));
                              break;
                    case '?': /* Error message printed */
                              break;
                    default:  abort ();
                }
    }

/* Print any remaining command line arguments (not options). */
if (optind < argc)
    {
        printf ("\nNon-option ARGV-elements: ");
while (optind < argc)
        printf ("%s ", argv[optind++]);
        putchar ('\n');
    }

/* check if all mandatory options are set and for unknown arguments */
/* This really needs changing... */
if (dip, sip, dport, sport == 0)
    {
        usage();
        return (-1);
    }

/* change */

pthread_t tid_pr;

if (pthread_create(&tid_pr, NULL, capture, NULL) != 0) {
    fprintf(stderr, "can't create raw packet reader: %s\n", strerror(errno));
    exit(1);
}
printf("\nRaw packet reader created\nWaiting 1 second for packet reader thread to settle down...\n\n");
sleep(1);

run();  

pthread_join(tid_pr, NULL);

getchar ();
exit (0);

}

int send_syn(unsigned int sourceip, unsigned int destip, unsigned short sourceport,
            unsigned short destport)
{
const int one = 1;
char buffer[PCKT_LEN];
struct sockaddr_in sin;
struct ipheader *ip;
struct tcpheader *tcp;

ip = (struct ipheader *) buffer;
tcp = (struct tcpheader *) buffer + ip->iph_ihl *4;

/* IP attributes */
ip->iph_ihl = 5;
ip->iph_ver = 4;
ip->iph_tos = 16;
ip->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
ip->iph_id = htons(54321);
ip->iph_offset = 0;
ip->iph_ttl = 64;
ip->iph_protocol = IPPROTO_TCP;
ip->iph_chksum = 0;                     
ip->iph_sourceip = sip;
ip->iph_destip = dip;
ip->iph_chksum = checksum ((unsigned short *) buffer, (sizeof (struct 
                            ipheader )+ sizeof (struct tcpheader)));            
/* TCP attributes */
tcp->tcph_sourceport = sport;
tcp->tcph_destport = dport;         
tcp->tcph_seqnum = htonl(1);        /* ADD SEQ NUM THINGY */
tcp->tcph_offset = 5;
tcp->tcph_flags = TH_SYN;
tcp->tcph_win = htons(32767);
tcp->tcph_chksum = 0; 
tcp->tcph_urgptr = 0;
tcp->tcph_chksum = (unsigned short) checksum_tcp((unsigned short) (ip->iph_len - ip->iph_ihl *4), (unsigned short *) &ip->iph_sourceip,
                    (unsigned short *) &ip->iph_destip, (unsigned short *) &tcp);       

/* Address family */ 
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ip->iph_destip;

/* Send */
if (sendto(sock, buffer, ip->iph_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    {
        fprintf(stderr, "\nCan't send packet\n");
        return (-1);
    }               
else
        printf("Packet sent to %d", dip); 

        close(sock);
}           

int send_syn_ack(unsigned int sourceip, unsigned int destip, unsigned short sourceport,
            unsigned short destport, unsigned long s_seq)   
{
const int one = 1;
char buffer[PCKT_LEN];
struct sockaddr_in sin;
struct ipheader *ip;
struct tcpheader *tcp;

ip = (struct ipheader *) buffer;
tcp = (struct tcpheader *) buffer + ip->iph_ihl *4;

/* IP attributes */
ip->iph_ihl = 5;
ip->iph_ver = 4;
ip->iph_tos = 16;
ip->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
ip->iph_id = htons(54321);
ip->iph_offset = 0;
ip->iph_ttl = 64;
ip->iph_protocol = IPPROTO_TCP;
ip->iph_chksum = 0;                     
ip->iph_sourceip = sip;
ip->iph_destip = dip;
ip->iph_chksum = checksum ((unsigned short *) buffer, (sizeof (struct 
                            ipheader )+ sizeof (struct tcpheader)));            
/* TCP attributes */
tcp->tcph_sourceport = sport;
tcp->tcph_destport = dport;         
tcp->tcph_seqnum = htonl(1 + 1);                        /* ADD SEQ NUM THINGY */
tcp->tcph_acknum = htonl (s_seq + 1);               /* ADD ACK NUM THINGY */
tcp->tcph_offset = 5;
tcp->tcph_flags = TH_ACK;
tcp->tcph_win = htons(32767);
tcp->tcph_chksum = 0; 
tcp->tcph_urgptr = 0;
tcp->tcph_chksum = (unsigned short) checksum_tcp((unsigned short) (ip->iph_len - ip->iph_ihl *4), (unsigned short *) &ip->iph_sourceip,
                    (unsigned short *) &ip->iph_destip,    (unsigned short *) &tcp);        


/* Address family */ 
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ip->iph_destip;

/* Send */
if (sendto(sock, buffer, ip->iph_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    {
        fprintf(stderr, "\nCan't send packet\n");
        return (-1);
    }               
else
        printf("Packet sent to %d\n", dip); 

        close(sock);
}       

void run()
{
const int one = 1;
char buffer[PCKT_LEN];
struct sockaddr_in sin; 
struct ipheader *ip;
struct tcpheader *tcp;

ip = (struct ipheader *) buffer;
tcp = (struct tcpheader *) buffer + ip->iph_ihl *4;

sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if (sock < 0)
    {
        fprintf(stderr, "\nSocket()\n\n");
        exit (-1);
    }
else
        printf ("socket() - Using SOCK_RAW and TCP protocol is OK.\n");

if ((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof (one))) < 0)
    {
        fprintf(stderr, "Can't set socketoptions\n");
        exit (-1);
    }
else
        printf("Socketoptions OK.\n");  

send_syn(dip, sip, dport, sport);
}

void receive(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *buffer)
{
const int one = 1;
int LEN = strtol(args, NULL, 0);        /* LEN = strtol(args, NULL, 0)   ----  int LEN = *args;*/
struct ipheader *ip;
struct tcpheader *tcp;

ip = (struct ipheader *)(buffer + LEN);
tcp = (struct tcpheader *)(buffer + LEN + sizeof (struct ipheader));

printf("%d\n", LEN);

printf("Packet received. ACK number: %d\n", ntohl (tcp->tcph_seqnum));
printf("Packet received. SEQ number: %d\n", ntohl (tcp->tcph_acknum));
s_seq = ntohl (tcp->tcph_seqnum);

send_syn_ack(s_seq, dip, sip, dport, sport);    

sleep(100);
}

void capture()
{
pcap_t *pd;
bpf_u_int32 netmask;
bpf_u_int32 localnet;
char filterbuf[64];
snprintf(filterbuf, sizeof(filterbuf), "ip dst host %s", dstip); 
char *filter = filterbuf;       
char *dev = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program filterprog;
int dl = 0, dl_len = 0;

if ((pd = pcap_open_live(dev, 1514, 1, 500, errbuf)) == NULL)       /* Look into snaplen size */
    {           
        fprintf(stderr, "can't open device %s: %s\n", dev, errbuf);
        exit(1);
    }

pcap_lookupnet(dev, &localnet, &netmask, errbuf);
pcap_compile(pd, &filterprog, filter, 0, localnet);
if (pcap_setfilter(pd, &filterprog) == - 1)
    {
        fprintf(stderr, "can't set pcap filter: %s %s\n", filter, errbuf);
        exit(1);
    }

pcap_freecode(&filterprog);
dl = pcap_datalink(pd);

switch(dl) {
    case 1:
        dl_len = 14;
        break;
    default:
        dl_len = 14;
        break;
}       

if (pcap_loop(pd, -1, receive, (u_char *) &dl_len) < 0) 
    {
        fprintf(stderr, "can't get raw packet: %s\n", pcap_geterr(pd));
        exit(1);
    }
}

void usage() 

{
/* This is the user manual (CHANGE) */  
printf("\nChannelBunny %s, created 2012\n\n", VERSION);

printf("ChannelBunny Usage:  -s -f <file> -i <destip> -p <destport> -o <sourceip> -t <sourceport>\n\n"); 

printf("-s, --send,             Puts program in send mode\n");
printf("-r, --receive,          Puts program in receive mode\n"); 
printf("-f, --file,             Specify file\n");       
printf("-i, --destip,           Destination IP address\n"); 
printf("-p, --destport,         Destination port\n"); 
printf("-o, --sourceip          Source IP address\n"); 
printf("-t, --sourceport        Source port\n");    
}
\define\u BSD\u源
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义版本“1.0”
#定义PCKT_LEN 8192
/*原型*/
int袜子;
无效运行();
无效捕获();
无效用法();
输入地址sip;
内加倾斜;
char*dstip=0;
内部序列;
国际体育;
int dport;
伪结构{
地址源IP中的结构;
地址destp中的结构;
无符号字符占位符;
无符号字符协议;
无符号字符tcp_len;
结构tcphdr-tcp;
};
结构ipheader{
未签名字符iph_ihl:5,
iph版本:4;
未签名字符iph_tos;
无符号短整数iph_len;
无符号短整数iph_id;
未签名字符iph_标志;
无符号短整数iph_偏移量;
无符号字符iph_ttl;
无符号字符iph_协议;
无符号短整数iph_chksum;
未签名的int-iph\u-sourceip;
未签名的int iph_destip;
};
结构tcpheader{
无符号短整数tcph_源端口;
无符号短整数tcph_destport;
无符号整数tcph_seqnum;
无符号整数tcph_acknum;
无符号字符tcph_保留:4,tcph_偏移量:4;
无符号字符tcph_标志;
无符号短整数tcph_-win;
无符号短整数tcph_chksum;
无符号短整数tcph_urgptr;
};
/*校验和*/
无符号短校验和(无符号短*pac,int len)
{ 
无符号长和;
对于(总和=0;len>0;len--)
总和+=*pac++;
总和=(总和>>16)+(总和&0xffff);
总和+=(总和>>16);
回报率(~sum);
}               
/*校验和TCP*/
无符号短校验和\u tcp(无符号短len,无符号短源IP[],
无符号短目标[],无符号短目标[])
{
无符号字符协议=6;
无符号长和;
int-nleft;
无符号短*w;
总和=0;
nleft=len;
w=buf;
而(nleft>1)
{
总和+=*w++;
nleft-=2;
}
如果(nleft>0)
{
总和+=*w&ntohs(0xFF00);
}
sum+=sourceip[0];
sum+=sourceip[1];
sum+=destip[0];
sum+=destip[1];
总和+=htons(len);
总和+=HTON(协议);
总和=(总和>>16)+(总和&0xFFFF);
总和+=(总和>>16);
sum=~sum;
返回((无符号短)和);
}
int main(int argc,字符**argv)
{
INTC;
/*我们在根吗?*/
如果(geteuid()!=0)
{
printf(“运行此程序需要根访问权限。\n\n”);
出口(0);
}   
而(1)
{
静态结构选项长_选项[]=
{
/*选择权*/
{“send”,没有_参数,0,'s'},/*args,r和f还没有函数*/
{“receive”,无_参数,0,'r'},
{“文件”,必需的参数,0,'f'},
{“destp”,必选参数,0,'i'},
{“destport”,必需的参数,0,'p'},
{“sourceip”,必需的参数,0,'o'},
{“sourceport”,必需的参数,0,'t'},
{0, 0, 0, 0}
};
int option_index=0;
c=getopt_long(argc,argv,“srf:d:i:p:o:t:”,
多头期权和期权指数);
/*检测选项的结尾*/
如果(c==-1)
打破
开关(c)
{
案例0:/*如果此选项设置了标志,则现在不执行其他操作*/
if(长选项[选项索引].flag!=0)
打破
printf(“选项%s”,长选项[选项索引].name);
如果(optarg)
printf(“带有参数%s”,optarg);
printf(“\n”);
打破
案例s:看跌期权(“期权-s\n”);
打破
案例“r”:看跌期权(“期权-r\n”);
打破
案例“f”:printf(“选项-f,值为“%s”\n”,optarg);
打破
案例“i”:dip=inet\U addr(optarg);
dstip=optarg;
打破
案例“p”:dport=htons(atoi(optarg));
/*在此处添加对错误/非数字输入的处理*/
打破
案例“o”:sip=inet\U addr(optarg);
打破
案例“t”:运动=htons(atoi(optarg));
打破
案例“?”:/*打印错误消息*/
打破
默认值:abort();
}
}
/*打印任何剩余的命令行参数(不是选项)*/
如果(选项D#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <pcap.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

#define VERSION "1.0"
#define PCKT_LEN 8192

/* Prototypes */    
int sock;   
void run();
void capture();
void usage(); 
in_addr_t sip;
in_addr_t dip;
char *dstip = 0;
int s_seq;
int sport;
int dport;              

struct pseudo {
struct in_addr sourceip;
struct in_addr destip;
unsigned char placeholder;
unsigned char protocol;
unsigned char tcp_len;
struct tcphdr tcp;
};

struct ipheader {

unsigned char       iph_ihl:5, 
                    iph_ver:4;
unsigned char       iph_tos;
unsigned short int  iph_len;
unsigned short int  iph_id;
unsigned char       iph_flags;
unsigned short int  iph_offset;
unsigned char       iph_ttl;
unsigned char       iph_protocol;
unsigned short int  iph_chksum;
unsigned int        iph_sourceip;
unsigned int        iph_destip;
};

struct tcpheader {
unsigned short int  tcph_sourceport;
unsigned short int  tcph_destport;
unsigned int        tcph_seqnum;
unsigned int        tcph_acknum;
unsigned char       tcph_reserved:4, tcph_offset:4;
unsigned char       tcph_flags;
unsigned short int  tcph_win;
unsigned short int  tcph_chksum;
unsigned short int  tcph_urgptr;
};



/* Checksum */
unsigned short checksum (unsigned short *pac, int len)
{ 
unsigned long sum;
for (sum = 0; len > 0; len--)
    sum += *pac++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return(~sum);
}               

/* Checksum TCP */
unsigned short checksum_tcp (unsigned short len, unsigned short sourceip[], 
                            unsigned short destip[], unsigned short buf[])
{
unsigned char protocol = 6;
unsigned long sum;
int nleft;
unsigned short *w;

sum = 0;
nleft = len;
w=buf;

while(nleft > 1)
    {
        sum += *w++;
        nleft -= 2;
    }
if(nleft > 0)
    {
        sum += *w&ntohs(0xFF00);
    }

sum += sourceip[0];
sum += sourceip[1];
sum += destip[0];
sum += destip[1];
sum += htons(len);
sum += htons(protocol);

sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);

sum = ~sum;
return ((unsigned short) sum);
}

int main(int argc,char **argv)
{
int c;

/* Are we in root? */   
if(geteuid() !=0)
    {
        printf("Root access is required to run this program.\n\n");
        exit(0);        
    }   

while (1)
    {
        static struct option long_options[] =
            {
                /* Options */
            {"send",       no_argument,       0, 's'}, /* args s, r and f have no function yet */
            {"receive",    no_argument,       0, 'r'},
            {"file",       required_argument, 0, 'f'}, 
            {"destip",     required_argument, 0, 'i'},
            {"destport",   required_argument, 0, 'p'},
            {"sourceip",   required_argument, 0, 'o'},
            {"sourceport", required_argument, 0, 't'},
            {0, 0, 0, 0}
            };

           int option_index = 0;

           c = getopt_long (argc, argv, "srf:d:i:p:o:t:",
                        long_options, &option_index);

                      /* Detect the end of the options. */
            if (c == -1)
                break;

            switch (c)
                {
                    case 0: /* If this option set a flag, do nothing else now. */
                            if (long_options[option_index].flag != 0)
                            break;
                                printf ("option %s", long_options[option_index].name);
                            if (optarg)
                                printf (" with arg %s", optarg);
                                printf ("\n");
                            break;

                    case 's': puts ("option -s\n");
                              break;
                    case 'r': puts ("option -r\n");
                              break;
                    case 'f': printf ("option -f with value `%s'\n", optarg);
                              break;
                    case 'i': dip = inet_addr(optarg);
                              dstip = optarg;
                              break;
                    case 'p': dport = htons(atoi(optarg)); 
                              /* Add handling of bad/non number input here */
                              break;
                    case 'o': sip = inet_addr(optarg);
                              break;
                    case 't': sport = htons(atoi(optarg));
                              break;
                    case '?': /* Error message printed */
                              break;
                    default:  abort ();
                }
    }

/* Print any remaining command line arguments (not options). */
if (optind < argc)
    {
        printf ("\nNon-option ARGV-elements: ");
while (optind < argc)
        printf ("%s ", argv[optind++]);
        putchar ('\n');
    }

/* check if all mandatory options are set and for unknown arguments */
/* This really needs changing... */
if (dip, sip, dport, sport == 0)
    {
        usage();
        return (-1);
    }

/* change */

pthread_t tid_pr;

if (pthread_create(&tid_pr, NULL, capture, NULL) != 0) {
    fprintf(stderr, "can't create raw packet reader: %s\n", strerror(errno));
    exit(1);
}
printf("\nRaw packet reader created\nWaiting 1 second for packet reader thread to settle down...\n\n");
sleep(1);

run();  

pthread_join(tid_pr, NULL);

getchar ();
exit (0);

}

int send_syn(unsigned int sourceip, unsigned int destip, unsigned short sourceport,
            unsigned short destport)
{
const int one = 1;
char buffer[PCKT_LEN];
struct sockaddr_in sin;
struct ipheader *ip;
struct tcpheader *tcp;

ip = (struct ipheader *) buffer;
tcp = (struct tcpheader *) buffer + ip->iph_ihl *4;

/* IP attributes */
ip->iph_ihl = 5;
ip->iph_ver = 4;
ip->iph_tos = 16;
ip->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
ip->iph_id = htons(54321);
ip->iph_offset = 0;
ip->iph_ttl = 64;
ip->iph_protocol = IPPROTO_TCP;
ip->iph_chksum = 0;                     
ip->iph_sourceip = sip;
ip->iph_destip = dip;
ip->iph_chksum = checksum ((unsigned short *) buffer, (sizeof (struct 
                            ipheader )+ sizeof (struct tcpheader)));            
/* TCP attributes */
tcp->tcph_sourceport = sport;
tcp->tcph_destport = dport;         
tcp->tcph_seqnum = htonl(1);        /* ADD SEQ NUM THINGY */
tcp->tcph_offset = 5;
tcp->tcph_flags = TH_SYN;
tcp->tcph_win = htons(32767);
tcp->tcph_chksum = 0; 
tcp->tcph_urgptr = 0;
tcp->tcph_chksum = (unsigned short) checksum_tcp((unsigned short) (ip->iph_len - ip->iph_ihl *4), (unsigned short *) &ip->iph_sourceip,
                    (unsigned short *) &ip->iph_destip, (unsigned short *) &tcp);       

/* Address family */ 
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ip->iph_destip;

/* Send */
if (sendto(sock, buffer, ip->iph_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    {
        fprintf(stderr, "\nCan't send packet\n");
        return (-1);
    }               
else
        printf("Packet sent to %d", dip); 

        close(sock);
}           

int send_syn_ack(unsigned int sourceip, unsigned int destip, unsigned short sourceport,
            unsigned short destport, unsigned long s_seq)   
{
const int one = 1;
char buffer[PCKT_LEN];
struct sockaddr_in sin;
struct ipheader *ip;
struct tcpheader *tcp;

ip = (struct ipheader *) buffer;
tcp = (struct tcpheader *) buffer + ip->iph_ihl *4;

/* IP attributes */
ip->iph_ihl = 5;
ip->iph_ver = 4;
ip->iph_tos = 16;
ip->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
ip->iph_id = htons(54321);
ip->iph_offset = 0;
ip->iph_ttl = 64;
ip->iph_protocol = IPPROTO_TCP;
ip->iph_chksum = 0;                     
ip->iph_sourceip = sip;
ip->iph_destip = dip;
ip->iph_chksum = checksum ((unsigned short *) buffer, (sizeof (struct 
                            ipheader )+ sizeof (struct tcpheader)));            
/* TCP attributes */
tcp->tcph_sourceport = sport;
tcp->tcph_destport = dport;         
tcp->tcph_seqnum = htonl(1 + 1);                        /* ADD SEQ NUM THINGY */
tcp->tcph_acknum = htonl (s_seq + 1);               /* ADD ACK NUM THINGY */
tcp->tcph_offset = 5;
tcp->tcph_flags = TH_ACK;
tcp->tcph_win = htons(32767);
tcp->tcph_chksum = 0; 
tcp->tcph_urgptr = 0;
tcp->tcph_chksum = (unsigned short) checksum_tcp((unsigned short) (ip->iph_len - ip->iph_ihl *4), (unsigned short *) &ip->iph_sourceip,
                    (unsigned short *) &ip->iph_destip,    (unsigned short *) &tcp);        


/* Address family */ 
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ip->iph_destip;

/* Send */
if (sendto(sock, buffer, ip->iph_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    {
        fprintf(stderr, "\nCan't send packet\n");
        return (-1);
    }               
else
        printf("Packet sent to %d\n", dip); 

        close(sock);
}       

void run()
{
const int one = 1;
char buffer[PCKT_LEN];
struct sockaddr_in sin; 
struct ipheader *ip;
struct tcpheader *tcp;

ip = (struct ipheader *) buffer;
tcp = (struct tcpheader *) buffer + ip->iph_ihl *4;

sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if (sock < 0)
    {
        fprintf(stderr, "\nSocket()\n\n");
        exit (-1);
    }
else
        printf ("socket() - Using SOCK_RAW and TCP protocol is OK.\n");

if ((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof (one))) < 0)
    {
        fprintf(stderr, "Can't set socketoptions\n");
        exit (-1);
    }
else
        printf("Socketoptions OK.\n");  

send_syn(dip, sip, dport, sport);
}

void receive(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *buffer)
{
const int one = 1;
int LEN = strtol(args, NULL, 0);        /* LEN = strtol(args, NULL, 0)   ----  int LEN = *args;*/
struct ipheader *ip;
struct tcpheader *tcp;

ip = (struct ipheader *)(buffer + LEN);
tcp = (struct tcpheader *)(buffer + LEN + sizeof (struct ipheader));

printf("%d\n", LEN);

printf("Packet received. ACK number: %d\n", ntohl (tcp->tcph_seqnum));
printf("Packet received. SEQ number: %d\n", ntohl (tcp->tcph_acknum));
s_seq = ntohl (tcp->tcph_seqnum);

send_syn_ack(s_seq, dip, sip, dport, sport);    

sleep(100);
}

void capture()
{
pcap_t *pd;
bpf_u_int32 netmask;
bpf_u_int32 localnet;
char filterbuf[64];
snprintf(filterbuf, sizeof(filterbuf), "ip dst host %s", dstip); 
char *filter = filterbuf;       
char *dev = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program filterprog;
int dl = 0, dl_len = 0;

if ((pd = pcap_open_live(dev, 1514, 1, 500, errbuf)) == NULL)       /* Look into snaplen size */
    {           
        fprintf(stderr, "can't open device %s: %s\n", dev, errbuf);
        exit(1);
    }

pcap_lookupnet(dev, &localnet, &netmask, errbuf);
pcap_compile(pd, &filterprog, filter, 0, localnet);
if (pcap_setfilter(pd, &filterprog) == - 1)
    {
        fprintf(stderr, "can't set pcap filter: %s %s\n", filter, errbuf);
        exit(1);
    }

pcap_freecode(&filterprog);
dl = pcap_datalink(pd);

switch(dl) {
    case 1:
        dl_len = 14;
        break;
    default:
        dl_len = 14;
        break;
}       

if (pcap_loop(pd, -1, receive, (u_char *) &dl_len) < 0) 
    {
        fprintf(stderr, "can't get raw packet: %s\n", pcap_geterr(pd));
        exit(1);
    }
}

void usage() 

{
/* This is the user manual (CHANGE) */  
printf("\nChannelBunny %s, created 2012\n\n", VERSION);

printf("ChannelBunny Usage:  -s -f <file> -i <destip> -p <destport> -o <sourceip> -t <sourceport>\n\n"); 

printf("-s, --send,             Puts program in send mode\n");
printf("-r, --receive,          Puts program in receive mode\n"); 
printf("-f, --file,             Specify file\n");       
printf("-i, --destip,           Destination IP address\n"); 
printf("-p, --destport,         Destination port\n"); 
printf("-o, --sourceip          Source IP address\n"); 
printf("-t, --sourceport        Source port\n");    
}
#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <pcap.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define VERSION "1.0"
#define PCKT_LEN 8192

/* Prototypes */
int sock;
void run();
void* capture(void *);
void usage();
in_addr_t sip;
in_addr_t dip;
char *dstip = 0;
int s_seq;
unsigned short sport;
unsigned short dport;

struct pseudo {
    struct in_addr sourceip;
    struct in_addr destip;
    unsigned char placeholder;
    unsigned char protocol;
    unsigned char tcp_len;
    struct tcphdr tcp;
};

struct ipheader {

    unsigned char       iph_ihl:5,
        iph_ver:4;
    unsigned char       iph_tos;
    unsigned short int  iph_len;
    unsigned short int  iph_id;
    unsigned char       iph_flags;
    unsigned short int  iph_offset;
    unsigned char       iph_ttl;
    unsigned char       iph_protocol;
    unsigned short int  iph_chksum;
    unsigned int        iph_sourceip;
    unsigned int        iph_destip;
};

struct tcpheader {
    unsigned short int  tcph_sourceport;
    unsigned short int  tcph_destport;
    unsigned int        tcph_seqnum;
    unsigned int        tcph_acknum;
    unsigned char       tcph_reserved:4, tcph_offset:4;
    unsigned char       tcph_flags;
    unsigned short int  tcph_win;
    unsigned short int  tcph_chksum;
    unsigned short int  tcph_urgptr;
};



/* Checksum */
unsigned short checksum (unsigned short *pac, int len)
{
    unsigned long sum;
    for (sum = 0; len > 0; len--)
        sum += *pac++;
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);

    return(~sum);
}

/* Checksum TCP */
unsigned short checksum_tcp (unsigned short len, unsigned short sourceip[],
    unsigned short destip[], unsigned short buf[])
{
    unsigned char protocol = 6;
    unsigned long sum;
    int nleft;
    unsigned short *w;

    sum = 0;
    nleft = len;
    w=buf;

    while(nleft > 1)
    {
        sum += *w++;
        nleft -= 2;
    }
    if(nleft > 0)
    {
        sum += *w&ntohs(0xFF00);
    }

    sum += sourceip[0];
    sum += sourceip[1];
    sum += destip[0];
    sum += destip[1];
    sum += htons(len);
    sum += htons(protocol);

    sum = (sum >> 16) + (sum & 0xFFFF);
    sum += (sum >> 16);
    sum = ~sum;

    return ((unsigned short) sum);
}

int main(int argc,char **argv)
{
    int c;

    /* Are we in root? */
    if(geteuid() !=0)
    {
        printf("Root access is required to run this program.\n\n");
        exit(0);
    }

    while (1)
    {
        static struct option long_options[] =
        {
        /* Options */
            {"send",       no_argument,       0, 's'}, /* args s, r and f have no function yet */
            {"receive",    no_argument,       0, 'r'},
            {"file",       required_argument, 0, 'f'},
            {"destip",     required_argument, 0, 'i'},
            {"destport",   required_argument, 0, 'p'},
            {"sourceip",   required_argument, 0, 'o'},
            {"sourceport", required_argument, 0, 't'},
            {0, 0, 0, 0}
        };

        int option_index = 0;
        c = getopt_long (argc, argv, "srf:d:i:p:o:t:",
        long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
            break;
        switch (c)
        {
            case 0: /* If this option set a flag, do nothing else now. */
            if (long_options[option_index].flag != 0)
                break;
            printf ("option %s", long_options[option_index].name);
            if (optarg)
                printf (" with arg %s", optarg);
            printf ("\n");
            break;

            case 's': puts ("option -s\n");
                break;
            case 'r': puts ("option -r\n");
                break;
            case 'f': printf ("option -f with value `%s'\n", optarg);
                break;
            case 'i': dip = inet_addr(optarg);
                dstip = optarg;
                break;
            case 'p': dport = htons(atoi(optarg));
                /* Add handling of bad/non number input here */
                break;
            case 'o': sip = inet_addr(optarg);
                break;
            case 't': sport = htons(atoi(optarg));
                break;
            case '?': /* Error message printed */
                break;
            default:  abort ();
        }
    }

    /* Print any remaining command line arguments (not options). */
    if (optind < argc)
    {
        printf ("\nNon-option ARGV-elements: ");
        while (optind < argc)
            printf ("%s ", argv[optind++]);
        putchar ('\n');
    }

    /* check if all mandatory options are set and for unknown arguments */
    /* This really needs changing... */
    if ((dip && sip && dport && sport) == 0)
    {
        usage();
        return (-1);
    }

    fprintf(stdout, "SPORT : %d, DPORT : %d\n", sport, dport);

    /* change */

    pthread_t tid_pr;
    if (pthread_create(&tid_pr, NULL, capture, NULL) != 0) {
        fprintf(stderr, "can't create raw packet reader: %s\n", strerror(errno));
        exit(1);
    }
    printf("\nRaw packet reader created\nWaiting 1 second for packet reader thread to settle down...\n\n");
    sleep(1);
    run();
    pthread_join(tid_pr, NULL);
    getchar ();

    exit (0);
}

int send_syn(unsigned int sourceip, unsigned int destip, unsigned short sourceport,
    unsigned short destport)
{
    //const int one = 1;
    char buffer[PCKT_LEN];
    struct sockaddr_in sin;
    struct ipheader *ip;
    struct tcpheader *tcp;

    ip = (struct ipheader *) buffer;
    tcp = (struct tcpheader *) buffer + ip->iph_ihl *4;

    /* IP attributes */
    ip->iph_ihl = 5;
    ip->iph_ver = 4;
    ip->iph_tos = 16;
    ip->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
    ip->iph_id = htons(54321);
    ip->iph_offset = 0;
    ip->iph_ttl = 64;
    ip->iph_protocol = IPPROTO_TCP;
    ip->iph_chksum = 0;
    ip->iph_sourceip = sip;
    ip->iph_destip = dip;
    ip->iph_chksum = checksum ((unsigned short *) buffer, (sizeof (struct
        ipheader )+ sizeof (struct tcpheader)));
    /* TCP attributes */
    tcp->tcph_sourceport = sport;
    tcp->tcph_destport = dport;
    tcp->tcph_seqnum = htonl(1);        /* ADD SEQ NUM THINGY */
    tcp->tcph_offset = 5;
    tcp->tcph_flags = TH_SYN;
    tcp->tcph_win = htons(32767);
    tcp->tcph_chksum = 0;
    tcp->tcph_urgptr = 0;
    tcp->tcph_chksum = (unsigned short) checksum_tcp((unsigned short) (ip->iph_len - ip->iph_ihl *4), (unsigned short *) &ip->iph_sourceip,
        (unsigned short *) &ip->iph_destip, (unsigned short *) &tcp);

    /* Address family */
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = ip->iph_destip;
    /* Send */
    if (sendto(sock, buffer, ip->iph_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    {
        fprintf(stderr, "\nCan't send packet\n");
        return (-1);
    }
    else
        printf("Packet sent to %d", dip);
    close(sock);

    return 0;
}

int send_syn_ack(unsigned int sourceip, unsigned int destip, unsigned short sourceport,
    unsigned short destport, unsigned long s_seq)
{
    //const int one = 1;
    char buffer[PCKT_LEN];
    struct sockaddr_in sin;
    struct ipheader *ip;
    struct tcpheader *tcp;

    ip = (struct ipheader *) buffer;
    tcp = (struct tcpheader *) buffer + ip->iph_ihl *4;
    /* IP attributes */
    ip->iph_ihl = 5;
    ip->iph_ver = 4;
    ip->iph_tos = 16;
    ip->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
    ip->iph_id = htons(54321);
    ip->iph_offset = 0;
    ip->iph_ttl = 64;
    ip->iph_protocol = IPPROTO_TCP;
    ip->iph_chksum = 0;
    ip->iph_sourceip = sip;
    ip->iph_destip = dip;
    ip->iph_chksum = checksum ((unsigned short *) buffer, (sizeof (struct
        ipheader )+ sizeof (struct tcpheader)));
    /* TCP attributes */
    tcp->tcph_sourceport = sport;
    tcp->tcph_destport = dport;
    tcp->tcph_seqnum = htonl(1 + 1);                        /* ADD SEQ NUM THINGY */
    tcp->tcph_acknum = htonl (s_seq + 1);               /* ADD ACK NUM THINGY */
    tcp->tcph_offset = 5;
    tcp->tcph_flags = TH_ACK;
    tcp->tcph_win = htons(32767);
    tcp->tcph_chksum = 0;
    tcp->tcph_urgptr = 0;
    tcp->tcph_chksum = (unsigned short) checksum_tcp((unsigned short) (ip->iph_len - ip->iph_ihl *4), (unsigned short *) &ip->iph_sourceip,
        (unsigned short *) &ip->iph_destip,    (unsigned short *) &tcp);

    /* Address family */
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = ip->iph_destip;
    /* Send */
    if (sendto(sock, buffer, ip->iph_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    {
        fprintf(stderr, "\nCan't send packet : %s\n", strerror(errno));
        return (-1);
    }
    else
        printf("Packet sent to %d\n", dip);
    close(sock);

    return 0;
}

void run()
{
    const int one = 1;
    //char buffer[PCKT_LEN];
    //struct sockaddr_in sin; 
    //struct ipheader *ip;
    //struct tcpheader *tcp;

    //ip = (struct ipheader *) buffer;
    //tcp = (struct tcpheader *) buffer + ip->iph_ihl *4;

    sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
    if (sock < 0)
    {
        fprintf(stderr, "\nSocket()\n\n");
        exit (-1);
    }
    else
        printf ("socket() - Using SOCK_RAW and TCP protocol is OK.\n");

    if ((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof (one))) < 0)
    {
        fprintf(stderr, "Can't set socketoptions\n");
        exit (-1);
    }
    else
        printf("Socketoptions OK.\n");
    send_syn(dip, sip, dport, sport);
}

void receive(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *buffer)
{
    //const int one = 1;
    //int LEN = strtol(args, NULL, 0);        /* LEN = strtol(args, NULL, 0)   ----  int LEN = *args;*/
    int LEN = atoi((char *)args);
    //struct ipheader *ip;
    struct tcpheader *tcp;

    //ip = (struct ipheader *)(buffer + LEN);
    tcp = (struct tcpheader *)(buffer + LEN + sizeof (struct ipheader));

    printf("LEN = %d\n", LEN);

    printf("Packet received. ACK number: %d\n", ntohl (tcp->tcph_seqnum));
    printf("Packet received. SEQ number: %d\n", ntohl (tcp->tcph_acknum));
    s_seq = ntohl (tcp->tcph_seqnum);

    send_syn_ack(s_seq, dip, sip, dport, sport);

    sleep(100);
}

void* capture(void *unused_arg)
{
    pcap_t *pd;
    bpf_u_int32 netmask;
    bpf_u_int32 localnet;
    char filterbuf[64];
    snprintf(filterbuf, sizeof(filterbuf), "ip dst host %s", dstip);
    char *filter = filterbuf;
    //char *dev = NULL;
    char dev[] = "eth0";
    char errbuf[PCAP_ERRBUF_SIZE];
    struct bpf_program filterprog;
    int dl = 0, dl_len = 0;
    /* TODO : SET THE INTERFACE CORRECTLY */
    //if ((pd = pcap_open_live(dev, 1514, 1, 500, errbuf)) == NULL)       /* Look into snaplen size */
    if ((pd = pcap_open_live(dev, 1514, 1, 500, errbuf)) == NULL)       /* Look into snaplen size */
    {
        fprintf(stderr, "can't open device %s: %s\n", dev, errbuf);
        exit(1);
    }

    pcap_lookupnet(dev, &localnet, &netmask, errbuf);
    pcap_compile(pd, &filterprog, filter, 0, localnet);
    if (pcap_setfilter(pd, &filterprog) == - 1)
    {
        fprintf(stderr, "can't set pcap filter: %s %s\n", filter, errbuf);
        exit(1);
    }

    pcap_freecode(&filterprog);
    dl = pcap_datalink(pd);

    switch(dl) {
        /* TODO : HANDLE THIS PART CORRECTLY */
        case 1:
            dl_len = 14;    /* Ethernet header */
            fprintf(stdout, "\nDL = %d (ETHERNET)\n", dl);
            break;
        default:
            dl_len = 14;
            fprintf(stdout, "\nDL = %d (if you are here please handle correctly)\n", dl);
            break;
    }
    if (pcap_loop(pd, -1, receive, (u_char *) &dl_len) < 0)
    {
        fprintf(stderr, "can't get raw packet: %s\n", pcap_geterr(pd));
        exit(1);
    }

    return NULL;
}

void usage()

{
    /* This is the user manual (CHANGE) */
    printf("\nChannelBunny %s, created 2012\n\n", VERSION);
    printf("ChannelBunny Usage:  -s -f <file> -i <destip> -p <destport> -o <sourceip> -t <sourceport>\n\n");
    printf("-s, --send,             Puts program in send mode\n");
    printf("-r, --receive,          Puts program in receive mode\n");
    printf("-f, --file,             Specify file\n");
    printf("-i, --destip,           Destination IP address\n");
    printf("-p, --destport,         Destination port\n");
    printf("-o, --sourceip          Source IP address\n");
    printf("-t, --sourceport        Source port\n");
}
fprintf(stdout, "Function : %s, Line : %d\n", __FUNCTION__, __LINE__);
int LEN = *(int *)args;
int LEN = strtol(args, NULL, 0);