LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-22-2012, 07:58 AM   #1
megustalinux
LQ Newbie
 
Registered: Jun 2012
Posts: 3

Rep: Reputation: Disabled
C - Program freezes; futex_wait_queue_me


I am having problems with my program going in futex_wait_queue_me mode.

I have included the code in its entirety so that you can test it if you want. Keep in mind that this is nowhere near completion, but should be able to send and recieve packets through a stable tcp connection.

When I run it I get:

Code:
./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.
and then it just hangs. I've also used strace and that gave me (only including the last bit where it stopped):

Code:
setsockopt(4, SOL_IP, IP_HDRINCL, [1], 4) = 0
    write(1, "Socketoptions OK.\n", 18Socketoptions OK.
    )     = 18
    sendto(4, "", 0, 0, {sa_family=AF_INET, sin_port=htons(63239), sin_addr=inet_addr("84.49.76.98")}, 16) = 0
    close(4)                                = 0
    futex(0x7f4c07bf89d0, FUTEX_WAIT, 3278, NULLsendto(4, "", 0, 0, {sa_family=AF_INET, sin_port=htons(63239), sin_addr=inet_addr("84.49.76.98")}, 16) = 0
    close(4)                                = 0
and the system monitor says the program is sleeping, and gives futex_wait_queue_me.

Code:
    #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"); 	
    }
 
Old 08-22-2012, 09:36 AM   #2
H_TeXMeX_H
Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269
I'm no expert but maybe this is not right:

Code:
int send_syn(unsigned int sourceip, unsigned int destip, unsigned short sourceport,
				unsigned short destport)
...
send_syn(dip, sip, dport, sport);
maybe it should be:

Code:
send_syn(sip, dip, sport, dport);
I haven't checked the entire code.
 
Old 08-22-2012, 10:36 AM   #3
megustalinux
LQ Newbie
 
Registered: Jun 2012
Posts: 3

Original Poster
Rep: Reputation: Disabled
Thanks for the effort TexMex but I'm afraid that had no effect. The frustrating bit is that there's almost no help in googling either.. just can't find anything useful (or rather that I can make use of).
 
Old 08-23-2012, 08:45 AM   #4
sundialsvcs
Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 5,381

Rep: Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109
Add more, more, more diagnostic print messages until you can zero-in on exactly where the messages stop. Make the debugging messages positively chatty.
 
Old 08-23-2012, 08:57 AM   #5
H_TeXMeX_H
Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269
Try using gdb as well. Load the file and see where it hangs.
 
  


Reply

Tags
freeze, sockets, tcp


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
futex_wait_queue_me issue that is all over the forums and no solutions Fred_mike Linux - General 6 01-20-2012 10:59 AM
`screen` program freezes sethb Linux - Server 3 09-23-2006 08:41 PM
OpenGL program freezes RH 9.0 ssd_123 Linux - Hardware 7 06-23-2003 08:54 AM
OpenGL program freezes RH 9.0 ssd_123 Linux - General 1 06-03-2003 01:55 PM
OpeGL program freezes RH 9.0 ssd_123 Linux - Newbie 1 06-03-2003 01:52 PM


All times are GMT -5. The time now is 09:40 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration