Friday, October 9, 2009

Sending ARP request in LINUX using C

#include "sys/socket.h"
#include "sys/types.h"
#include "stdio.h"
#include "unistd.h"
#include "string.h"
#include "net/if.h"
#include "stdlib.h"
#include "arpa/inet.h"
#include "netinet/in.h"
#include "sys/ioctl.h"
#include "netpacket/packet.h"
#include "net/ethernet.h"
#include "netdb.h

#define ETHER_TYPE_FOR_ARP 0x0806
#define HW_TYPE_FOR_ETHER 0x0001
#define OP_CODE_FOR_ARP_REQ 0x0001
#define HW_LEN_FOR_ETHER 0x06
#define HW_LEN_FOR_IP 0x04
#define PROTO_TYPE_FOR_IP 0x0800

typedef unsigned char byte1;
typedef unsigned short int byte2;
typedef unsigned long int byte4;

// For Proper memory allocation in the structure
#pragma pack(1)
typedef struct arp_packet
{
// ETH Header
byte1 dest_mac[6];
byte1 src_mac[6];
byte2 ether_type;
// ARP Header
byte2 hw_type;
byte2 proto_type;
byte1 hw_size;
byte1 proto_size;
byte2 arp_opcode;
byte1 sender_mac[6];
byte4 sender_ip;
byte1 target_mac[6];
byte4 target_ip;
// Paddign
char padding[18];
}ARP_PKT;

int print_pkt(char *, int len);

int main(int argc, char *argv[])
{
int arp_fd,if_fd,retVal;
struct sockaddr_in *sin;
struct sockaddr_ll sa;
struct ifreq ifr;
ARP_PKT pkt;
unsigned long int ipAddr;

if( argc != 3 )
{
printf("Usage: ./arp \n");
exit(1);
}
else if( getuid() && geteuid())
{
printf("Oops!\nDude you need SuperUser rights!\n");
exit(1);
}

/*=============================START of IP, MAC ADDRESS ACCESS========================*/

/* Open socket for accessing the IPv4 address of specified Interface */
if_fd = socket(AF_INET, SOCK_STREAM, 0);
if( if_fd < 0 )
{
perror("IF Socket");
exit(1);
}

/* provide interface name to ifreq structure */
memcpy(ifr.ifr_name, argv[1], IF_NAMESIZE);
/* IOCTL to get ip address */
retVal = ioctl(if_fd, SIOCGIFADDR, &ifr, sizeof(ifr));
if( retVal < 0 )
{
perror("IOCTL");
close(if_fd);
exit(1);
}

/* Simple typecasting for easy access to ip address */
sin = (struct sockaddr_in *)&ifr.ifr_addr;
ipAddr = ntohl(sin->sin_addr.s_addr);
#ifdef DBG_ARP
printf("IF Name: %s IP Address: %s ",argv[1], inet_ntoa(sin->sin_addr));
printf("IP = 0x%x\n",ipAddr);
#endif

retVal = ioctl(if_fd, SIOCGIFHWADDR, &ifr, sizeof(ifr));
if( retVal < 0 )
{
perror("IOCTL");
close(if_fd);
exit(1);
}
#ifdef DBG_ARP
printf("MAC address: %s is %02x:%02x:%02x:%02x:%02x:%02x \n",
argv[1],
ifr.ifr_hwaddr.sa_data[0]&0xFF,
ifr.ifr_hwaddr.sa_data[1]&0xFF,
ifr.ifr_hwaddr.sa_data[2]&0xFF,
ifr.ifr_hwaddr.sa_data[3]&0xFF,
ifr.ifr_hwaddr.sa_data[4]&0xFF,
ifr.ifr_hwaddr.sa_data[5]&0xFF);
#endif

/*-----------------------------END of IP,MAC ADDRESS ACCESS------------------------*/

/*=============================Start of ARP request sending====================*/
// Socket to send ARP packet
arp_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
if( arp_fd == -1 )
{
perror("ARP Socket");
close(if_fd);
exit(1);
}

//====================== Formulate the ARP Packet ============================
// Ethernet Header
memset(pkt.dest_mac, 0xFF, (6 * sizeof(byte1)));
memset(pkt.src_mac, (ifr.ifr_hwaddr.sa_data[0]&0xFF), sizeof(byte1));
memset(pkt.src_mac+1, (ifr.ifr_hwaddr.sa_data[1]&0xFF), sizeof(byte1));
memset(pkt.src_mac+2, (ifr.ifr_hwaddr.sa_data[2]&0xFF), sizeof(byte1));
memset(pkt.src_mac+3, (ifr.ifr_hwaddr.sa_data[3]&0xFF), sizeof(byte1));
memset(pkt.src_mac+4, (ifr.ifr_hwaddr.sa_data[4]&0xFF), sizeof(byte1));
memset(pkt.src_mac+5, (ifr.ifr_hwaddr.sa_data[5]&0xFF), sizeof(byte1));
pkt.ether_type = htons(ETHER_TYPE_FOR_ARP);
// ARP Header
pkt.hw_type = htons(HW_TYPE_FOR_ETHER);
pkt.proto_type = htons(PROTO_TYPE_FOR_IP);
pkt.hw_size = HW_LEN_FOR_ETHER;
pkt.proto_size = HW_LEN_FOR_IP;
pkt.arp_opcode = htons(OP_CODE_FOR_ARP_REQ);
memcpy(pkt.sender_mac, pkt.src_mac, (6 * sizeof(byte1)));
pkt.sender_ip = htonl(ipAddr);
memset(pkt.target_mac, 0 , (6 * sizeof(byte1)));
pkt.target_ip = inet_addr(argv[2]);
// Padding
memset(pkt.padding, 0 , 18 * sizeof(byte1));


// For sending the packet We need it!
retVal = ioctl(if_fd, SIOCGIFINDEX, &ifr, sizeof(ifr));
if( retVal < 0 )
{
perror("IOCTL");
close(arp_fd);
close(if_fd);
exit(1);
}
sa.sll_family = AF_PACKET;
sa.sll_ifindex = ifr.ifr_ifindex;
sa.sll_protocol = htons(ETH_P_ARP);

/* Send it! */
retVal = sendto(arp_fd, &pkt, sizeof(pkt), 0,(struct sockaddr *)&sa, sizeof(sa));
if( retVal < 0 )
{
perror("sendto");
close(arp_fd);
close(if_fd);
exit(1);
}

#ifdef DBG_ARP
printf("\n=========PACKET=========\n");
print_pkt((void *)&pkt, sizeof(pkt));
#endif
return 0;
}

int print_pkt(char *buf, int len)
{
int j = 0;
for(j = 0; j < len; j++ )
{
if((j%16) == 0 && j != 0 )
printf("\n");
printf("%02x ",*(buf+j)& 0xFF );
}
printf("\n");
return 0;
}

Tuesday, September 29, 2009

Read ARP entry Linux

/******************************************************
Author : Chaitu
Date : 29/09/2009
Description : Reading MAC address from kernel arp table
in Linux
*******************************************************/
#include "sys/types.h"
#include "sys/socket.h"
#include "sys/time.h"
#include "sys/ioctl.h"
#include "net/route.h"
#include "stdio.h"
#include "errno.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "arpa/inet.h"
#include "netinet/ether.h"
#include "netpacket/packet.h"
#include "net/if.h"

int main(int argc, char **argv)
{
struct sockaddr_in *sin;
struct arpreq myreq;
int sockfd;

if(argc != 3)
{
printf("Usage:./mac \n");
exit(1);
}
/* Initialize the structure */
memset(&myreq, '\0', sizeof(myreq));

/* AF_INET family is must */
sin = (struct sockaddr_in *)&myreq.arp_pa;
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = inet_addr(argv[2]); // Give the IP for which MAC is needed

sin = (struct sockaddr_in *)&myreq.arp_ha;
sin->sin_family = AF_INET;

memcpy(myreq.arp_dev,argv[1],IFNAMSIZ - 1);

/* Open socket for IOCTL operation */
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("socket");
exit(1);
}

/* IOCTL for accessing the MAC address */
if((ioctl(sockfd, SIOCGARP,&myreq, sizeof(myreq)) < 0))
{
perror("ioctl");
close(sockfd);
exit(1);
}

printf("mac address of IP:%s is %02x:%02x:%02x:%02x:%02x:%02x\n", argv[2],( myreq.arp_ha.sa_data[0]&0xFF),
(myreq.arp_ha.sa_data[1]&0xFF),
(myreq.arp_ha.sa_data[2]&0xFF),
(myreq.arp_ha.sa_data[3]&0xFF),
(myreq.arp_ha.sa_data[4]&0xFF),
(myreq.arp_ha.sa_data[5]&0xFF));

return 0;
}

Sunday, August 30, 2009

example for multi processing in linux

/*SERVER PROGRAM*/



#include
#include
#include
#include
#include
#include
#include
#include
#include

struct sockaddr_in add2,add1;

socklen_t len,len1;

int i,j,k,l,z;

int fm2[10];

int fd[2];

int ff1,ff2;
int status;
int pid,n;
int sock2;


void sigchld_handler()
{
read(fd[0],&j,sizeof(int));
read(fd[0],&k,sizeof(int));

i--;

fm2[j]=0; //SETTING FIFO STATUS 0 FOR IDLE 1 FOR BUSY
fm2[k]=0; //SETTING FIFO STATUS 0 FOR IDLE 1 FOR BUSY


printf("\nStatus Array at exit and i is %d\n",i);
for(l=0;l<10;l++)
printf("%d\n",fm2[l]);

}


void sigint_handler()
{
printf("\nSERVER is being terminated........\n");
if(pid!=getpid())
{

printf("\nClient Process with pid is %u Terminating\n",getpid())
;

n=1;
write(ff2,&n,sizeof(int));

sleep(1);
n=0;
write(sock2,&n,sizeof(int));

shutdown(sock2,SHUT_RDWR);
}

sleep(1);
exit(0);
}


void sigpipe_handler()
{
write(fd[1],&j,sizeof(int));
write(fd[1],&k,sizeof(int));
exit(0);
}



main()
{

int bin,sock,tmp;
char ch='t';

char fm1[10][3]={"f0","f1","f2","f3","f4","f5","f6","f7","f8","f9"};


//HANDLING CHILD PROCESS TERMINATION WHICH IS KILLED OR STOPPED

signal(SIGCHLD,sigchld_handler);

//HANDLING CTRL+Ci

signal(SIGINT,sigint_handler);

signal(SIGPIPE,sigpipe_handler);

signal(SIGQUIT,sigint_handler);
//PIPE CREATION FOR SENDING THE FIFO ARRAY STATUS

pipe(fd);

//SERVER SOCKET CREATION

sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("Server Socket Creation Error\n");
exit(1);
}

add1.sin_port=htons(4500);
add1.sin_addr.s_addr=INADDR_ANY;
add1.sin_family=AF_INET;

//BINDING SERVER SOCKET.

if(bind(sock,(struct sockaddr *)&add1,sizeof(add1))<0)
{
perror("Binding Error\n");
exit(1);
}

//LISTENING FOR CONNECTIONS.

i=listen(sock,5);
if(i<0)
{
perror("Listen error\n");
exit(1);
}

pid=getpid();

printf("\nServer Process id is %u\n",getpid());
//SETTING FIFO ARRAY STATUS AS IDLE BEFORE ACCEPTING CLIENT CONNECTIONS

for(i=0;i<10;i++)
fm2[i]=0;

//i VALUE MAINTAINS NUMBER OF CONNECTIONS

i=0;
while(1)
{

if(i<5)
{

//ACCEPT SIGNAL

sock2=accept(sock,(struct sockaddr *)&add2,&len1);
if(sock2<0)
{
perror("Accept Error\n");
exit(1);
}

// printf("\nI value is %d\n",i);

//i VALUE IS INCREMENTED AS A NEW CLIENT CONNECTION ACCEPTED.

i++;

//FIFO MANAGEMENTSTARTING

j=0;
while(fm2[j]!=0)
{
j++;
}
fm2[j]=1;


k=0;
while(fm2[k]!=0)
{
k++;
}
fm2[k]=1;



printf("\nStatus Array before and i is %d\n",i);
for(l=0;l<10;l++)
printf("%d\n",fm2[l]);
//FIFO MANAGEMENT CLOSED

//SPAWNING A NEW PROCESS FOR EACH AND EVERY NEW CLIENT CONNECTION


pid=fork();
if(pid==-1)
{
perror("FORK error\n");
}

//EXECUTING THE CHILD PROCESS

if(pid==0)
{

//SENDING THE FIFO NAMES TO CLIENT THROUGH WHICH COMMUNICATION HAS TO BE DONE.

write(sock2,&fm1[j],2);
write(sock2,&fm1[k],2);

ff1=open(fm1[j],O_RDONLY);
if(ff1==-1)
{
perror("OPENING FIRST FIFO\n");
}

ff2=open(fm1[k],O_WRONLY);
if(ff2==-1)
{
perror("OPENING SECOND FIFO\n ");
}

//SERVER DATA INTERFACE MODULE STARTS.


printf("pid is %u\n",getpid());

while(1)
{

read(ff1,&ch,sizeof(char));

//ENCRYPTION PART STARTS
// ch=ch ^ 'a' ;
//ENCRYPTION PART ENDS
n=1;
write(sock2,&n,sizeof(int));

if(ch==0)
{
break;
}

sleep(1);
write(ff2,&ch,sizeof(char));
}

//SERVER DATA INTERFACE MODULE ENDS.

close(ff1);
close(ff2);


write(fd[1],&j,sizeof(int));
write(fd[1],&k,sizeof(int));
// write(fd[1],&z,sizeof(int));


shutdown(sock2,SHUT_RDWR);

exit(0);
}

}

}

shutdown(sock,SHUT_RDWR);

}


/*CLIENT PROGRAM*/


#include
#include
#include
#include
#include
#include
#include
#include

struct sockaddr_in add;

void onerror(char *);

int sd,i,n;

int fd1, fd2;
int ff1,ff2,z;

char *j;
char ch='a';


void sigint_handler()
{

i=0;
write(ff1,&i,sizeof(int));

close(fd1);
close(fd2);

close(ff1);
close(ff2);

unlink(j);

shutdown(sd,SHUT_RDWR);

printf("\nChild process terminated because of SIGINT\n");

exit(0);
}



void sigpipe_handler()
{
printf("\nPIPE BROKEN\n");
exit(0);
}


main(int argc, char *argv[])
{

int bin,tmp,i=0,jk;

char f1n[3],f2n[3];

char s[10], *k=".";

//Signal Mechanisms for ctrl+c i.e SIGINT

signal(SIGINT,sigint_handler);

//Signal Mechanisms for broken pipe i.e SIGPIPE

signal(SIGPIPE,sigpipe_handler);

//Signal Mechanisms for ctrl+\ i.e SIGQUIT

signal(SIGQUIT,sigint_handler);

//Checking for number of input arguments provided during runtime.

if(argc<3)
{
printf("No Sufficient arguments supplied \n");
printf("Please provide full path for the file\n");
exit(0);
}

//CREATING CLIENT SOCKET

sd=socket(AF_INET,SOCK_STREAM,0);
if(sd<0)
{
perror("Client Socket Creation Error\n");
exit(1);
}


add.sin_port=htons(4500);
add.sin_addr.s_addr=inet_addr("127.0.0.1");
add.sin_family=AF_INET;

//CONNECTING CLIENT SOCKET
if(connect(sd,(struct sockaddr *)&add,sizeof(add))<0)
{
perror("Connection Error\n");
exit(1);
}


for(i=0;i<3;i++)
{
f1n[i]='\0';
f2n[i]='\0';
}

//READING FIFO NAMES FROM SERVER THROUGH WHICH COMMUNICATION PROCEEDS IN FUTURE.

if(read(sd,f1n,2)<0)
{
onerror("FIFO1 Error\n");
}
if(read(sd,f2n,2)<0)
{
onerror("FIFO2 Error\n");
}

printf("FIFO1 is %s\n",f1n);
printf("FIFO2 is %s\n",f2n);

//OPENING SENDER FIFO THROUGH WHICH DATA IS SENT TO SERVER

ff1=open(f1n,O_RDWR);
if(ff1==-1)
{
onerror("FIFO1 opening ERROR");
}

//OPENING RECEIVER FIFO THROUGH WHICH CLIENT RECEIVES ENCRYPTED DATA

ff2=open(f2n,O_RDWR);
if(ff2==-1)
{
onerror("FIFO2 opening ERROR\n");
}


//OPENING THE SOURCE FILE WHICH CONTAINS DATA TO BE ENCRYPTED

fd1=open(argv[1],O_RDONLY);
if(fd1<0)
{
onerror("Input File doesn't Exist\n");

}

//Mechanism to produce output filename as .

i=getpid();
z=strlen(argv[2]);

j=(char *)malloc(z);
strcpy(j,argv[2]);

sprintf(s,"%d",i);
strcat(j,k);
strcat(j,s);

//j contains output file name

//OPENING OUTPUT FILE INTO WHICH ENCRYPTED DATA IS STORED.

fd2=open(j,O_WRONLY|O_CREAT,0666);
if(fd2<0)
{
onerror("Opening Encryption File Error\n");
}


while(1)
{

// printf("\nSTART\n");

z=read(fd1,&ch,sizeof(char));
if(z==-1)
{
onerror("Read from Input file Error\n");
}


if(z==0)
{
write(ff1,&z,sizeof(int));
break;
}


else if(write(ff1,&ch,sizeof(char))<0)
{
onerror("Write into FIFO Error\n");
}


// printf("\nMIDDLE\n");


if(read(sd,&n,sizeof(int))<0)
{
onerror("\nRead from Socket Error\n");
}


if(n!=0)
{
// printf("\nInside If\n");


if(read(ff2,&ch,sizeof(char))<0)
{
onerror("Read from FIFO Error\n");
}

if(write(fd2,&ch,sizeof(char))<0)
{
onerror("Write into Encrypted File Error\n");
}
}

else
{

printf("\nInside else\n");
close(fd1);
close(fd2);

close(ff1);
close(ff2);

unlink(j);
exit(0);
}

// printf("\nEND\n");
}


close(fd1);
close(fd2);

close(ff1);
close(ff2);

shutdown(sd,SHUT_RDWR);

printf("\n\nSocket connection with Server closed Successfully\n");
}


void onerror(char *msg)
{

printf("\nERROR!! %s\n",msg);

shutdown(sd,SHUT_RDWR);
printf("\nSocket Connection Closed Abruptly\n");
exit(0);
}