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;
}