Thread: Raw Socket Client and Server Communication Problem

  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    2

    Raw Socket Client and Server Communication Problem

    I have been trying to communicate between my client and server program. I have checked and rechecked the man pages and it seems my syntax is correct. I'm trying to send packets from my client to my server and the server prints out the host name. My server seemed to receive the packets once during testing. I say this because it printed out my "check statements" and seemed to find the host name from the sent packets. All it is doing now though is attempting to bind to the server's port and seems to be waiting on something to send from the client. If someone could take a look at this I would really appreciate it. Thank you for your time--rgpii.

    Here is my code below:

    ip and udp header file

    Code:
    //Header file for our ip header and udp header structures.
     
    // The packet length
    #define PCKT_LEN 8192
     
    // Can create separate header file (.h) for all headers' structure
    // The IP header's structure
    struct ipheader {
     unsigned char      iph_ihl:4;// IP Header Length 
     unsigned char 	    iph_ver:4;//Internet Protocol
     unsigned char      iph_tos;//Type of Service
     unsigned short int iph_len;//Length of IP datagram. Must include UDP size.
     unsigned short int iph_ident;//ID sequence number.
     unsigned char      iph_flag;
     unsigned short int iph_offset;//Fragment offset-used for broken datagrams
     unsigned char      iph_ttl;//Time to live-amount of hops before packet is discarded.
     unsigned char      iph_protocol;//Transport layer protocol.UDP(17)
     unsigned short int iph_chksum;//Checksum total.Everytime header changes must be recalculated.
     unsigned int       iph_sourceip;//Source IP must be converted into binary. inet_pton()
     unsigned int       iph_destip;//Destination IP ""
    };
     
    // UDP header's structure
    struct udpheader {
     unsigned short int udph_srcport;
     unsigned short int udph_destport;
     unsigned short int udph_len;
     unsigned short int udph_chksum;
    };
    Check Sum header file.
    Code:
    //Header file for the check sum algorithm.
    unsigned short 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);
    
        }
    Client Program:

    Code:
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <netinet/ip.h>
    #include <netinet/udp.h>
    #include <string.h>
    #include "ipudp.h"
    #include "csum.h"
    
    						/******Client Program*****/
    
    
    int main(int argc, char *argv[])
    {
    printf("Beginning Raw Socket Programming\n");
    //Variable Declarations 
    int sfd;
    char buffer[PCKT_LEN];
    struct ipheader *ip=(struct ipheader*) buffer;//Rename to iph
    struct udpheader *udp=(struct udpheader*)(buffer +sizeof(struct ipheader));//Rename to udph
    struct sockaddr_in sin, din;//DOES NOT HAVE TO BE SIN AND DIN!!!
    int one=1;
    const int *val=&one;//Curious to the purpose of this? Test later with just constant integer.
    memset(buffer,0,PCKT_LEN);//Memset to ensure no packet corruption?
    
    //Baby Argument Checker
    if(argc!=5){
    printf("Invalid Parameters\n");
    	}
    
    /*Argument Checking*******This is the servers. The letters need to be changed back to the clients.
    int argcounter;
    printf("Number of arguments %d\n", argc);
    for(argcounter=1;argcounter<14;argcounter++)
    	{
    	printf("Before switch argcounter is %d\n",argcounter);
    	 switch(argv[argcounter][1])
    		{
    		case 'p':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'r':		
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'q':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'l':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'f':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'h':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 't':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break; 
    		default:
    		printf("Incorrect Argument Use\n");
    		break;
    		}*/
    
    
    //Creating a raw socket using the UDP protocol.
    sfd=socket(PF_INET,SOCK_RAW,IPPROTO_UDP);
    if(sfd<0){
    perror("socket() error\n");
    exit(-1);
    }
    else{
    printf("Socket was created\n");
    }
    //The Address Familys for my sockadd_in structs.
    sin.sin_family=AF_INET;
    din.sin_family=AF_INET;
    //Port Numbers--This will go in my argument checker.
    sin.sin_port=htons(atoi(argv[2]));
    din.sin_port=htons(atoi(argv[4]));
    //IP Addresses--This will go in my argument checker--Used old way in internet example.(E.g "inet_address()")
    if(inet_pton(AF_INET,argv[1],&sin.sin_addr)<0){
    perror("inet_pton() error\n");
    }
    if(inet_pton(AF_INET,argv[3],&din.sin_addr)<0){
    perror("inet_pton() error\n");
    }
    //Creating my own IP Header
    ip->iph_ihl=4;
    ip->iph_ver=4;
    ip->iph_tos=16;
    ip->iph_len=sizeof(struct ipheader)+sizeof(struct udpheader);
    ip->iph_ident=htons(54321);
    ip->iph_ttl=64;
    ip->iph_protocol=17;
    //Source IP Address
    if(inet_pton(AF_INET,argv[1],&ip->iph_sourceip)<0){
    perror("inet_pton() error\n");
    }
    if(inet_pton(AF_INET,argv[3],&ip->iph_destip)<0){
    perror("inet_pton() error\n");
    }
    //Creating UDP Header
    udp->udph_srcport=htons(atoi(argv[2]));
    udp->udph_destport=htons(atoi(argv[4]));
    udp->udph_len=htons(sizeof(struct udpheader));
    //Calculating Checksum for my packet
    ip->iph_chksum=csum((unsigned short*)buffer,sizeof(struct ipheader) + sizeof(struct udpheader));
    //Informing the kernel not to fill the packet. We will do that.
    if(setsockopt(sfd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one))<0){
    perror("setsockopt() error\n");
    exit(-1);
    }
    else{
    printf("setsockopt() is doing ok\n");
    }
    
    printf("Using:::::Source IP: %s port: %u, Target IP: %s port: %u.\n", argv[1], atoi(argv[2]), argv[3], atoi(argv[4]));
    int count;
    for(count = 0; count < 40; count++)
    {
    if(sendto(sfd,buffer,ip->iph_len,0,(struct sockaddr*)&sin,sizeof(sin))<0){
    perror("sendto() error\n");
    }
    else{
    printf("Count #%u - sendto() is OK\n", count);
    sleep(2);
    }
    }
    close(sfd);
    return 0;
    }
    Server Program:

    Code:
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <netinet/ip.h>
    #include <netinet/udp.h>
    #include <string.h>
    #include "ipudp.h"
    #include "csum.h"
    #define SERVER_PORT	5020 
    
    	/******Server Program*****/*
    
    int main(int argc, char* argv[])
    {
    //Variable Declarations
    int sfd;
    //int  new_sfd;
    char buffer[PCKT_LEN];
    char hbuf[NI_MAXHOST],sbuf[NI_MAXSERV];
    //struct ipheader *ip=(struct ipheader*)buffer;//Rename to iph
    //struct udpheader *udp=(struct udpheader*)(buffer + sizeof(struct ipheader));//Rename to udph
    struct sockaddr_in sin, din;//DOES NOT HAVE TO BE SIN AND DIN!!!
    //int one=1;
    //**Unused Variable const int *val=&one;
    struct sockaddr_storage inc_packet;
    socklen_t inc_packetl;
    int bytes_read;
    memset(buffer,0,PCKT_LEN);
    	
    /*
    //Argument Checking
    int argcounter;
    printf("Number of arguments %d\n", argc);
    for(argcounter=1;argcounter<14;argcounter++)
    	{
    	printf("Before switch argcounter is %d\n",argcounter);
    	 switch(argv[argcounter][1])
    		{
    		case 'p':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'r':		
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'q':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'l':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'f':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 'h':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break;
    		case 't':
    		argcounter++;
    		printf("Heck Yeah Made it to %s\n",argv[argcounter]);
    		break; 
    		default:
    		printf("Incorrect Argument Use\n");
    		break;
    		}
    	}
    */
    //Address Family
    sin.sin_family=AF_INET;
    din.sin_family=AF_INET;
    //Port Numbers
    sin.sin_port=htons(SERVER_PORT);
    //din.sin_port=client port argument.
    //IP Addresses
    if(inet_pton(AF_INET,"127.0.0.1",&sin.sin_addr)<0){
    perror("inet_pton() error\n");
    }
    else{
    printf("inet_pton() doing ok\n");
    }
    //Include IP Address for Client
    
    //Creating a raw socket using the UDP protocol.
    sfd=socket(PF_INET,SOCK_RAW,IPPROTO_UDP);
    if(sfd<0){
    perror("socket() error\n");
    exit(-1);
    }
    else{
    printf("Socket was created\n");
    }
    //Binding our socket to our servers port.
    if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){
    perror("bind() error\n");
    exit(-1);
    }
    else{
    printf("bind() is doing ok\n");
    }
    int x =0;
    while(x!=10){
    printf("Waiting after bind\n");
    inc_packetl=sizeof(struct sockaddr_storage);
    bytes_read=recvfrom(sfd,buffer,PCKT_LEN,0,(struct sockaddr*)&inc_packet,&inc_packetl);  
    if(bytes_read==0){
    printf("Message Read\n");
    }
    printf("Printing Buffer Stuff %s\n",buffer);
    if(getnameinfo((struct sockaddr*)&inc_packet,inc_packetl,hbuf,sizeof(hbuf),sbuf,sizeof(sbuf),0)<0){
    perror("getnameinfo() error\n");
    }
    else{
    printf("Host name found\n");
    }
    printf("Host:%s,  Serv:%s\n",hbuf,sbuf); 
    x++;
    }
    close(sfd);
    return 0;
    }

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Ummmm... Why all the trouble to make your own headers when sockets builds it's own on the fly and attaches it to every datagram you send? Believe me it's using it's own headers not yours... all you're doing is making your code more complex than it needs to be...

    Here's what I use...
    Code:
    // initialize Client port/return port number
    WORD InitNetwork(WORD Port,HWND Win,PTCHAR Password)
      { WSADATA     wsadata;              // winsock startup
        TCHAR       hn[MAX_HOSTNAME];     // host name
        DWORD       hs = MAX_HOSTNAME;    // host name size
        SOCKADDR    la;                   // local address
        WORD        lp = Port;            // local port
        // Load the Winsock DLL
        if (WSAStartup(MAKEWORD(2,0),&wsadata))
          return 0;
        // initialize local socket
        hSocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        if (hSocket == INVALID_SOCKET)
          return 0;
        // initialize localhost IP  
        GetComputerName(hn,&hs);
        if (!GetHostAddr(hn,Port,&la))
          return 0;
        // bind on user designated Port
        if(bind(hSocket,&la,sizeof(SOCKADDR)))
          return 0; 
         return lp; }
    That sets up a listening UDP socket... from there just call sendto() and receivefrom()... there is absolutely no need to create your own headers, sockets does all that for you.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    It looks like copy/paste code from 3 different people.

    FYI, an indent style of "none" or "chaos" means your code will largely go unread.
    SourceForge.net: Indentation - cpwiki
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Salem View Post
    It looks like copy/paste code from 3 different people.
    Yep... scoop and poop .... Definately not the way to do things.

  5. #5
    Registered User
    Join Date
    Feb 2011
    Posts
    2
    Sorry about the formatting. Is it against the rules if i repost the code again but formatted? It is necessary for me to create my own headers because that is part of my assignment. I also noticed the above poster is using "winsock"? I believe that is windows specific. Right? I am sorry I'm on a Linux machine. I am currently running Ubuntu. I don't know if that will help or not.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Yes, please post again with formatting.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by rplumii View Post
    Sorry about the formatting. Is it against the rules if i repost the code again but formatted? It is necessary for me to create my own headers because that is part of my assignment. I also noticed the above poster is using "winsock"? I believe that is windows specific. Right? I am sorry I'm on a Linux machine. I am currently running Ubuntu. I don't know if that will help or not.
    It makes no difference about sockets or winsock... they're both derived from the Berkley Sockets library and they intercommunicate freely... The only difference is the wsastartup() call to load the library.

    Creating your own headers is a total waste of time and in your original example, it resulted in dormant code... You may want to ask your teacher what he meant by "create your own headers" since, at the socket level, you actually have no access to tcp/ip headers at all.
    Last edited by CommonTater; 02-10-2011 at 07:40 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. raw socket to dgram communication
    By cole701 in forum Networking/Device Communication
    Replies: 3
    Last Post: 09-02-2010, 03:46 PM
  2. Replies: 15
    Last Post: 10-20-2009, 09:39 AM
  3. Socket Programming Problem!!!!
    By bobthebullet990 in forum Networking/Device Communication
    Replies: 2
    Last Post: 02-21-2008, 07:36 PM
  4. Where's the EPIPE signal?
    By marc.andrysco in forum Networking/Device Communication
    Replies: 0
    Last Post: 12-23-2006, 08:04 PM
  5. socket newbie, losing a few chars from server to client
    By registering in forum Linux Programming
    Replies: 2
    Last Post: 06-07-2003, 11:48 AM