Ask for a strange question

This is a discussion on Ask for a strange question within the Linux Programming forums, part of the Platform Specific Boards category; I write codes about sending TCP packet and receiving IP and TCP packet, I create a socket: sk=socket(AF_INET,SOCK_RAW,IPPROTO_TCP); if I ...

  1. #1
    Registered User
    Join Date
    Jun 2011
    Posts
    50

    Ask for a strange question

    I write codes about sending TCP packet and receiving IP and TCP packet,
    I create a socket:
    sk=socket(AF_INET,SOCK_RAW,IPPROTO_TCP);
    if I set the option:
    setsockopt(sk, IPPROTO_IP, IP_HDRINCL,&on,sizeof(on));(int on=1)
    then I send combining packet of IP and TCP ,then I can receive IP and TCP packet.
    If I don't set the option IP_HDRINCL,and I send only TCP packet,
    when I receive packet,it display error:Resource temporarily unavailable.
    Who could tell me why?and how to correct it?thank you very much.

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    50
    And I find If I set my local IP to real IP(not INADDRY_ANY),when I recieve it
    display "invalid argument" ,if I set my local IP to INADDRY_ANY,when I recieve it
    display "Resource temporarily unavailable" .My codes send TCP packet at first,
    and then receive data.Who could tell me why?and how to correct it?

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,498
    Quote Originally Posted by leetow2003 View Post
    I write codes about sending TCP packet and receiving IP and TCP packet,
    Code? What code? I don't see any code. It's near impossible for us to troubleshoot this without code.

    Who could tell me why?and how to correct it?thank you very much.
    Nobody. Not because your question is impossible to answer, because we don't have enough information.

    What are you communicating with or using to generate the packets for testing? Are you sure that doesn't have a bug?

    Read the following man pages: socket(7), ip(7), packet(7), raw(7)
    The 7 is for section 7, so do "man 7 socket".

    Here's a StackOverflow article that looks related. Maybe some of the info there will give you some clues.

  4. #4
    Registered User
    Join Date
    Jun 2011
    Posts
    50
    Because my codes are too long,
    Look:
    Code:
    #define LOCALPORT   8888 
    //pseudo header,12 bytes
    struct prseuheader
    {
    unsigned long s_addr;//resource addr
    unsigned long d_addr;//dest addr
    unsigned char zero;  //0
    unsigned char prototp;//tcp=6
    unsigned short len;   //length
    };
    
    /*20 bytes*/
    struct IP_Head
    {
        unsigned char  length:4;          
        unsigned char  version:4;         
        unsigned char  tos;               
        unsigned short total_length;      
        unsigned short id;                
        unsigned short flagoff;           
        unsigned char  ttl;              
        unsigned char  protocol;          
        unsigned short cksum;             
        unsigned int   source;            
        unsigned int   dest;             
    };
    
    /* 20 bytes */
    struct TCP_Head
    {
        unsigned short source_port;      
        unsigned short dest_port;        
        unsigned int   seqno;            
        unsigned int   ackno;            
        unsigned char  rev1:4;           
        unsigned char  len:4;            
        unsigned char  fin:1;            
        unsigned char  syn:1;           
        unsigned char  rst:1;            
        unsigned char  psh:1;           
        unsigned char  ack:1;           
        unsigned char  urg:1;            
        unsigned char  rev2:2;          
        unsigned short winsize;         
        unsigned short cksum;            
        unsigned short urgent;           
    };
    
    static struct sockaddr_in Localaddr;//Local IP address
    static struct sockaddr_in RemoteAddr;//remote IP address
    
    /* Checksum  */
    unsigned short checksum(unsigned short* buffer, int size)
    {
    unsigned long cksum = 0;
    while(size>1)
    {
        cksum += *buffer++;
        size -= 2;
    }
    if(size)
    {
        cksum += *(u_char*)buffer;
    }
    cksum = (cksum>>16) + (cksum&0xffff);  
    cksum += (cksum>>16);          
    return (unsigned short)(~cksum);
    }
    
    //main 
    int main()
    {
    	int sk;
    	char ipaddr[16]="192.168.1.6";//remote IP
    	struct in_addr in;
    	inet_aton(ipaddr,&in);
    	//set RemoteAddr
    	bzero(&RemoteAddr,sizeof(struct sockaddr_in));
                 RemoteAddr.sin_family=AF_INET;
                 RemoteAddr.sin_addr=in;
    
                 sk=socket(AF_INET,SOCK_RAW,IPPROTO_TCP);  //create SOCK_RAW
                if(sk<0)
                {
                  perror("socket error");
                  return -1;
                }
    
    	int iRet;
    	struct timeval timeout={1,0}; //timeout
    	int len=sizeof(struct timeval);
    
    	//set timeout
    	iRet =setsockopt(sk,SOL_SOCKET,SO_SNDTIMEO, &timeout,len);
                 if (iRet<0)
                {
                   perror("[Error]Set socket SO_SNDTIMEO option");
                   close(sk);
                  return -1; 
                }
    	iRet =setsockopt(sk,SOL_SOCKET,SO_RCVTIMEO, &timeout,len);
                if (iRet<0)
                {
                   perror("[Error]Set socket SO_RCVTIMEO option");
                   close(sk);
                  return -1; 
                }
    		
    	    
                 bzero(&Localaddr,sizeof(struct sockaddr_in));
                 Localaddr.sin_family=AF_INET;
    	Localaddr.sin_addr.s_addr=inet_addr("192.168.124.128"); //My PC's real IP
    	
                 iRet = bind(sk,(struct sockaddr*)&Localaddr,sizeof(struct sockaddr)); 
                 if (iRet<0)
                {
                   perror("[Error]Bind sk the interface");
                   close(sk);
                   return -1;
                 }
        
    	struct TCP_Head Tcph;//TCP packet
    	struct IP_TCP_Head
    	{
                     struct IP_Head  Iph; 
                     struct TCP_Head Tcph;
    	}*Reply;    //for receiving
    	struct prseuheader theheader;//pseudo header
    	char tcpbuff[32];  //pseudo header and TCP header
    	unsigned char buffer[200];   //buffer for receiving
    	struct sockaddr_in taddr;   //
    	int lenfrom,lenrecv;
    
                bzero(&Tcph,20);
    	Tcph.source_port  =htons(8888);//local port
                //Tcph.dest_port    =htons(21);//dest port;
                Tcph.seqno        =0;
    	Tcph.ackno        =0;
    	Tcph.len          =5;
    	Tcph.syn          =1;      //SYN=1
    	Tcph.winsize      =htons(6000);
    	Tcph.cksum        =0;
                 bzero(tcpbuff,32);
        //fill 
        theheader.s_addr = Localaddr.sin_addr.s_addr; 
        theheader.d_addr = RemoteAddr.sin_addr.s_addr;
        theheader.zero = 0;
        theheader.prototp = 6;  // protocol of TCP
        theheader.len = htons(20); //length of TCP   
        //pseudo header+TCP header
        memcpy(tcpbuff,&theheader,12);
        memcpy(tcpbuff+12,&Tcph,20);
    	//Tcph.cksum        =checksum((unsigned short *)tcpbuff,32);
    	int port=21;
    	//for(port=1;port<30;port++)
    	{
         	Tcph.dest_port    =htons(port);
                 memcpy(tcpbuff+12,&Tcph,20); 
                 Tcph.cksum        =0;
                 Tcph.cksum        =checksum((unsigned short *)tcpbuff,32); 
    	//sending data
    	iRet=sendto(sk,(unsigned char*)&Tcph,20,0,(struct sockaddr*)&RemoteAddr,sizeof(struct sockaddr_in)); 
      	if(iRet<0)
    	  perror("error sendto");
    	//receiving data
        bzero(buffer,200); 
    	bzero(&taddr,sizeof(taddr));
        lenrecv=recvfrom(sk,buffer,200,0,(struct sockaddr*)&taddr,&lenfrom); 
    	if(lenrecv>0) /*it express PC has received data*/
    	{
           Reply=(struct IP_TCP_Head*)buffer;
    	   printf("syn,ask=%d,%d\n",(Reply->Tcph).syn,(Reply->Tcph).ack);
    	   if((Reply->Tcph).syn==1 &&(Reply->Tcph).ack==1 && (Reply->Iph).source==RemoteAddr.sin_addr.s_addr && (Reply->Iph).dest==Localaddr.sin_addr.s_addr)
           {
    		   printf("active Port:%d\n",21);
               bzero(Reply,sizeof(Reply));
            }
    		
    	 }
    	 else
    	 {
    		 //it always displays 
              printf("len=%d\n",lenrecv);  
    	      perror("recv len");
    		 
    	  }
        }
     return 0;
    }

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,498
    That code is not too long, and very necessary for our helping you. It would be nice if you showed which headers you included as well. Did you read the man pages thoroughly for all the functions you're using? I'm guessing not. A quick Google search would tell you that "Resource temporarily unavailable" was tied to EAGAIN or EWOULDBLOCK. So looking at the man page:
    Quote Originally Posted by man recvfrom
    ERRORS
    These are some standard errors generated by the socket layer. Additional errors may be generated and returned from the underlying protocol modules; see their manual
    pages.


    EAGAIN or EWOULDBLOCK
    The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received.
    POSIX.1-2001 allows either error to be returned for this case, and does not require these constants to have the same value, so a portable application should check
    for both possibilities.
    That's probably why you're getting that error message. You set a timeout of 1 second, and it expired. Again, I can't say for sure what the origin of that error is, but for some reason 192.168.1.6 is not replying. Perhaps you have some malformed packets. Perhaps nothing is actually listening on that IP/port on the TCP protocol. Port 21 is FTP, so are you sure you can connect from 192.168.124.128 to .1.6 on port 21? Use the standard Linux FTP client. Capture that dialogue with Wireshark. Then, run your program and capture that dialogue with Wireshark. Compare the two. How is your SYN packet different that of the working FTP client's? Also, is there a reason you have the checksum commented out?


    Lastly, you should stop using bzero as it's deprecated. Just use memset (again, the man page tells you this).

  6. #6
    Registered User
    Join Date
    Jun 2011
    Posts
    50
    I can connect 192.168.1.6 port 21 using command ftp,and just now I find if
    set recvfrom buffer to 2000,it runs well,why?

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,498
    The only way I can imagine enlarging your receive buffer could affect how the program works is if you have a buffer overflow somewhere. If that buffer overflow used to destroy other variables on the stack, and now it can't get that far up the stack because buffer is too big, then that might explain it. I didn't see anything, but that doesn't mean I didn't miss it. I found your code a little messy and hard to follow. Try using valgrind and electric fence to make sure you're behaving yourself, and maybe step through your code in GDB and inspect every value as you go.

    If that's not the issue, then perhaps something on the network or remote server changed since this morning. Otherwise, I have no ideas at the moment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange question here: do you know how to program a PIC?
    By Dante Wingates in forum General Discussions
    Replies: 16
    Last Post: 11-28-2010, 06:30 PM
  2. Strange question mark at EOF
    By Babkockdood in forum C Programming
    Replies: 5
    Last Post: 06-09-2010, 10:43 AM
  3. A strange question, I know.
    By cyreon in forum C++ Programming
    Replies: 22
    Last Post: 01-30-2008, 02:21 PM
  4. Strange memset question
    By Death_Wraith in forum Game Programming
    Replies: 14
    Last Post: 09-25-2004, 12:58 AM
  5. strange strange functions
    By threahdead in forum C Programming
    Replies: 4
    Last Post: 10-13-2002, 05:31 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21