Monday, July 19, 2010

udp send

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

int fd,num_pkt;
void sig_handler(int num)
{
printf("sent %d packets\n",num_pkt);
close(fd);
exit(1);
}

void print_pkt(unsigned *buf, int len)
{
int j;

for(j=0; j< len; j++)
{
if(j%16 == 0 || j != 0)
printf("\n");
printf("%02x ",buf[j]);
}
printf("\n");
}

struct _udp_packet
{
struct udphdr udp;
unsigned char data[22];
}__attribute__((__packed__));

int main(int argc, char **argv)
{
struct sockaddr_in sin;
struct _udp_packet udpkt;

if(argc != 4)
{
printf("Usage:\n./udp \n");
exit(1);
}

fd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
if(fd < 0)
{
perror("socket");
exit(1);
}

sin.sin_family = AF_INET;
//sin.sin_port = htons(atoi(argv[1]);
sin.sin_addr.s_addr = inet_addr(argv[3]);

udpkt.udp.source = htons(atoi(argv[2]));
udpkt.udp.dest = htons(atoi(argv[1]));
udpkt.udp.len = htons(8 + sizeof(udpkt.data));
udpkt.udp.check = 0x0000;

memset(udpkt.data, 0, sizeof(udpkt.data));

signal(SIGINT,sig_handler);
signal(SIGQUIT,sig_handler);
while(1)
{

if(sendto(fd, (unsigned char*)&udpkt, 30, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr)) < 0)
{
perror("sendto");
close(fd);
exit(1);
}

num_pkt++;
sleep(1);
}

return 0;
}

Saturday, March 13, 2010

Kid Ping Utility

/*****************************************************
* Author : Chaitanya bhargav M
* Date : 13 March 2010
* License : Free, but unreliable
* Description : Simpler ping without any options,
created just for fun!
*****************************************************/

#include<stdio.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/time.h>
#include<sys/param.h>
#include<linux/if_ether.h>
#include<linux/ip.h>
#include<linux/icmp.h>
#include<linux/if_packet.h>
#include<net/if.h>
#include<string.h>
#include<stdlib.h>
#include<signal.h>

int sock_fd,transmitted = 0,received = 0;
float t_sum = 0;

void sig_handler(int sigNum)
{
printf("\n=======================ping stats======================");
printf("\n%d packets transmitted, %d received, avg.delay = %.3fms\n",transmitted,received,(t_sum/received));
printf("Packet loss = %d%%,",((transmitted-received)/(transmitted))*100);
printf(" Thanks for using! -Chaitu\n");
close(sock_fd);
exit(127);
}

#pragma pack(1)
struct _icmp_{
struct icmphdr icmp;
unsigned char data[22];
}packet;

unsigned short check_sum(unsigned char *buf, int len);
char *ip_ntoa(unsigned int ipAddr)
{
char *ip = (char *)malloc(16);
sprintf(ip,"%d.%d.%d.%d",(ipAddr&0xff000000)>>24,
(ipAddr&0x00ff0000)>>16,
(ipAddr&0x0000ff00)>>8,
(ipAddr&0x000000ff));
return ip;
}

struct timezone tz;
int main(int argc, char *argv[])
{
int retVal,sin_size,data_len;
unsigned short seq = 0x0000;
struct iphdr *ip;
struct icmphdr *icmp;
struct sockaddr_in whereto,sin ;
struct timeval *tp = (struct timeval *)&packet.data[0];
struct timeval *tp1;
struct timeval tv;
float delay;

if(argc != 2)
{
printf("Usage:\n ./pinger \n");
exit(127);
}

whereto.sin_family = AF_INET;
whereto.sin_addr.s_addr = inet_addr(argv[1]);
memset(&packet.data[0],0,22);
unsigned char buf[1518];

sock_fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if(sock_fd < 0)
{
perror("socket");
exit(127);
}

signal(SIGINT,sig_handler);

while(1)
{
/* Send the packet */
gettimeofday(tp, &tz);
packet.icmp.type = ICMP_ECHO;
packet.icmp.code = 0;
packet.icmp.checksum = 0;
packet.icmp.un.echo.id = htons(0xc000);
packet.icmp.un.echo.sequence = htons(++seq);
packet.icmp.checksum = htons(check_sum((unsigned char *)&packet.icmp.type,30));
retVal = sendto(sock_fd, (unsigned char *)&packet, 30, 0,(struct sockaddr *) &whereto, sizeof(struct sockaddr));
if(retVal < 0)
{
perror("send to");
close(sock_fd);
exit(127);
}
transmitted++;

/* Receive Packet */
data_len = recvfrom(sock_fd, buf, 1518, 0 ,(struct sockaddr *)&sin, &sin_size);
ip = (struct iphdr *)buf;
icmp = (struct icmphdr *)(buf + ((ip->ihl) << 2));
if(icmp->type == ICMP_ECHOREPLY)
{
if(icmp->un.echo.id == htons(0xc000))
{
if(icmp->un.echo.sequence == htons(seq))
{
gettimeofday(&tv, &tz);
delay = (tv.tv_sec) - (tp->tv_sec) + (tv.tv_usec) - (tp->tv_usec);
printf("64 bytes from %s icmp_seq=%d ttl=%d delay=%.3fms\n",ip_ntoa(ntohl(ip->saddr)),seq,ip->ttl,(delay/1000));
received++;
t_sum += (delay/1000);
}
}
}
sleep(1);
}
return ;
}

unsigned short check_sum(unsigned char *buf, int len)
{
unsigned short len_16 = 0;
unsigned int len_32 = 0;
int i;

for(i =0; i < len; i+=2)
{
len_16 = (buf[i] << 8)&0xff00 | buf[i+1]&0xff;
len_32 += len_16;
}
if(len_32 >> 16)
{
len_32 = ((len_32>>16)&0xffff) + (len_32&0xffff);
}
if(len_32 >> 16)
{
len_32 = ((len_32>>16)&0xffff) + (len_32&0xffff);
}
len_32 = ~len_32;

return (len_32&0xffff);
}

Sunday, March 7, 2010

Kid Sniffer

/**************************************************************************
* Author : Chaitanya bhargav M
* date Created : 07 March 2010
* License : free, but unreliable
* ************************************************************************/
#include unistd.h
#include stdio.h
#include net/if.h
#include sys/socket.h
#include sys/types.h
#include sys/time.h
#include string.h
#include stdlib.h
#include linux/in.h
#include netinet/ether.h
#include linux/if_ether.h
#include linux/if_packet.h
#include linux/ip.h
#include linux/icmp.h
#include linux/udp.h
#include linux/tcp.h
#include signal.h
#include linux/if_vlan.h
#include linux/if_arp.h

/**************************
* Namesake signal Handler
**************************/
void signal_handle(int sigNum)
{
printf("Received the signal : %d",sigNum);
exit(128);
}

/*********************************************************
* Converts ipAddress in integer to dotted decimal format
*********************************************************/
char *ip_ntoa(unsigned int ip)
{
char *str = (char *)malloc(16*sizeof(char));
sprintf(str,"%d.%d.%d.%d",(ip&0xff000000)>>24,
(ip&0x00ff0000)>>16,
(ip&0x0000ff00)>>8,
(ip&0x000000ff));
return str;
}

/*****************************
* Process packets in Layer 3
*****************************/
void process_ip_packet(unsigned char *buf, int len)
{
struct iphdr *ip;
struct icmphdr *icmp;
struct udphdr *udp;
struct tcphdr *tcp;

//printf("Received a packet with size:%d\n",len);
ip = (struct iphdr *)(buf );
printf("ip_src:%s > ip_dst:%s,", ip_ntoa(ntohl(ip->saddr)),ip_ntoa(ntohl(ip->daddr)));
switch( ip->protocol)
{
case IPPROTO_ICMP:
icmp = (struct icmphdr *)(buf + (ip->ihl << 2));
if(icmp->type == ICMP_ECHO)
{
printf("ICMP Echo req \n");
}
else if(icmp->type == ICMP_ECHOREPLY)
{
printf("ICMP Echo reply \n");
}
else if(icmp->type == ICMP_DEST_UNREACH)
{
printf("ICMP Destination Unreachable\n");
}
break;
case IPPROTO_UDP:
udp = (struct udphdr *)(buf + (ip->ihl << 2));
printf("UDP, src: %d, dest: %d\n",ntohs(udp->source), ntohs(udp->dest));
break;
case IPPROTO_TCP:
tcp = (struct tcphdr *)(buf + (ip->ihl << 2));
printf("TCP, src: %d, dest: %d\n",ntohs(tcp->source), ntohs(tcp->dest));
break;
default:
printf("Unconcerned IP Protocol:0x%04x\n",ip->protocol);
break;
}
return ;
}

/********************************
* Process packets in Link Layer
********************************/
void process_frame(unsigned char *buffer, int len)
{
//printf("Received a packet with size:%d\n",len);
struct ethhdr *eth;
struct vlan_ethhdr *vlaneth;
struct iphdr *ip;
struct arp_hdr *arp;

eth = (struct ethhdr *) buffer;
printf("%02x:%02x:%02x:%02x:%02x:%02x > %02x:%02x:%02x:%02x:%02x:%02x,",eth->h_source[0],eth->h_source[1],
eth->h_source[2],eth->h_source[3],
eth->h_source[4],eth->h_source[5],
eth->h_dest[0],eth->h_dest[1],
eth->h_dest[2],eth->h_dest[3],
eth->h_dest[4],eth->h_dest[5]);
switch(ntohs(eth->h_proto))
{
case ETH_P_ARP:
arp = (struct arp_hdr *)(buffer + ETH_HLEN);
if(ntohs(arp->ar_op) == ARPOP_REQUEST)
{
printf("ARP Request for IP:%d.%d.%d.%d tell IP:%d.%d.%d.%d\n",arp->ar_tip[0],arp->ar_tip[1],arp->ar_tip[2],arp->ar_tip[3],
arp->ar_sip[0],arp->ar_sip[1],arp->ar_sip[2],arp->ar_sip[3]);
}
else if(ntohs(arp->ar_op) == ARPOP_REPLY)
{
printf("ARP Reply for IP:%d.%d.%d.%d is MAC:%02x:%02x:%02x:%02x:%02x:%02x\n",arp->ar_sip[0],arp->ar_sip[1],arp->ar_sip[2],arp->ar_sip[3],
arp->ar_sha[0],arp->ar_sha[1],arp->ar_sha[2],arp->ar_sha[3],arp->ar_sha[4],arp->ar_sha[5]); }
break;

case ETH_P_8021Q:
break;

case ETH_P_IP:
process_ip_packet( buffer+ETH_HLEN, len-ETH_HLEN);
break;

case ETH_P_IPV6:
printf("IPV6 packet\n");
break;

default:
printf("Some strange protocol:0x%04x\n",ntohs(eth->h_proto));
break;
}
return ;
}

/**************************************************
* Main Function: Accessing the packets from stack
**************************************************/
int main(int argc, char *argv[])
{
int fd,retVal = 0,sin_size,data_size;
unsigned char buffer[1522];
struct sockaddr_in sin;

fd = socket(PF_PACKET, SOCK_RAW,htons(ETH_P_ALL) );
if(fd == -1)
{
perror("Raw socket");
exit(127);
}

signal(SIGINT, signal_handle);
signal(SIGSEGV, signal_handle);
signal(SIGFPE, signal_handle);

sin_size = sizeof sin;
while(1)
{
data_size = recvfrom(fd, buffer, 1518, 0,(struct sockaddr *) &sin, &sin_size);
process_frame(buffer, data_size);
}

return 0;
}

//============= E O F =================

Monday, December 14, 2009

Sending ICMP request using C program

/**********************************************************************************
* AUTHOR : Chaitanya bhargav M
* Date : 14/10/2009
* description : To send an icmp request to specified host via specified
* Interface.
* License : Never mind to do any thing with this code.But, it might be unreliable
* *********************************************************************************
* CopyLeft(c) Chaitanya bhargav M 2009
***********************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

typedef unsigned long int uint32;
typedef unsigned short int uint16;
typedef unsigned char uint8;

#define ETHER_TYPE_FOR_IP 0x0800
#define PROTOCOL_ICMP 0x01

// For proper memory allocation for each packet
#pragma pack(1)
// Ethernet header
typedef struct eth_hdr
{
uint8 dest_mac[6];
uint8 src_mac[6];
uint16 ether_type;
}ETH_HDR;
// 802.1Q Header
typedef struct vlan_hdr
{
uint16 type;
uint16 vlanID;
}VLAN_HDR;
// IP Header without options
typedef struct ip_hdr
{
uint8 version_headerlen;
uint8 diffserv;
uint16 total_len;
uint16 ident;
uint8 flags;
uint8 frag_offset;
uint8 ttl;
uint8 protocol;
uint16 checksum;
uint32 src_addr;
uint32 dest_addr;
}IP_HDR;
// ICMP Header
typedef struct icmp_hdr
{
uint8 type;
uint8 code;
uint16 checksum;
uint16 ident;
uint16 seq_no;
}ICMP_HDR;
// My own ICMP packet
typedef struct icmp_packet
{
ETH_HDR eth;
IP_HDR ip;
ICMP_HDR icmp;
uint8 data[32];
}ICMP_PKT;

// Function prototypes to calculate checksum and to print packet
unsigned short int header_checksum(char *, unsigned short int );
int print_pkt( char *, unsigned short int );

int main(int argc, char *argv[])
{
struct sockaddr_in *sin;
struct ifreq ifr;
struct sockaddr_ll sa;
int if_fd,icmp_fd,retVal,arp_flagg = 1;
unsigned long int ipAddr,IfIndex;
unsigned char IfMac[6];
ICMP_PKT pkt;
// It's my gateway. So, i am hardcoding
unsigned char gateway[7] = { 0x00,0x1A,0x6D,0x2B,0x89,0x29 };

if(argc != 3)
{
printf("Usage:\n ./icmp_req \n");
exit(1);
}

if(getuid() && geteuid())
{
printf("Oops!\n No Super user right\n");
exit(1);
}

// Check for default gateway
if(!strcmp(argv[1],"eth0"))
{
arp_flagg = 0;
}

if_fd = socket(AF_INET, SOCK_DGRAM, 0);
if( if_fd < 0 )
{
perror("If Socket");
exit(1);
}

//==============================Interface related data======================
// provide Interface name
strcpy(ifr.ifr_name,argv[1]);

// IP address
retVal = ioctl( if_fd, SIOCGIFADDR, &ifr, sizeof(ifr));
if( retVal < 0 )
{
perror("IFADDR IOCTL");
close(if_fd);
exit(1);
}
sin = (struct sockaddr_in *)&ifr.ifr_addr;
ipAddr = ntohl(sin->sin_addr.s_addr);

#ifdef DBG_ICMP
printf("IpAddr = %s\n",inet_ntoa(sin->sin_addr));
#endif

// MAC address
retVal = ioctl(if_fd, SIOCGIFHWADDR, &ifr, sizeof(ifr));
if( retVal < 0)
{
perror("IFHWADDR IOCTL");
close(if_fd);
exit(1);
}
memcpy(IfMac, ifr.ifr_hwaddr.sa_data, 6 * sizeof(unsigned char));

#ifdef DBG_ICMP
printf("MAC = %02x:%02x:%02x:%02x:%02x:%02x\n", IfMac[0],IfMac[1],IfMac[2],IfMac[3],IfMac[4],IfMac[5]);
#endif

// Interface index
retVal = ioctl(if_fd, SIOCGIFINDEX, &ifr, sizeof(ifr));
if( retVal < 0)
{
perror("IFINDEX");
close(if_fd);
exit(1);
}

#ifdef DBG_ICMP
printf("IfIndex = %d\n",ifr.ifr_ifindex);
#endif

IfIndex = ifr.ifr_ifindex;
//==============================Interface related data=====================

//==============================Packet socket==============================

icmp_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
if(icmp_fd < 0 )
{
perror("ICMP Socket");
close(if_fd);
exit(1);
}

//=============================Frame the packet============================
// Ethernet header
if(!arp_flagg) // If sending via gateway
{
memcpy(pkt.eth.dest_mac, gateway, 6 * sizeof(unsigned char));
}
else // If sending via private interface
{
memset(pkt.eth.dest_mac, 0xFF, 6 * sizeof(unsigned char));
}
memcpy(pkt.eth.src_mac, IfMac, 6 * sizeof(unsigned char));
pkt.eth.ether_type = htons(ETHER_TYPE_FOR_IP);

// IP header
pkt.ip.version_headerlen = 0x45; // version = IPv4, len = 5 (x 32 = 160)
pkt.ip.diffserv = 0x00; // Best effort
pkt.ip.total_len = htons(0x003C); // 20 IP header + 8 UDP header + 32 data
pkt.ip.ident = htons(0xa9b1); // just to identify reply
pkt.ip.flags = 0x00; // no fragmentation
pkt.ip.frag_offset = htons(0x0000); // no fragmentaion
pkt.ip.ttl = 0x80; // let's give 128
pkt.ip.protocol = PROTOCOL_ICMP; // ICMP protocol inside IP
pkt.ip.checksum = htons(0x0000); // Will be found out after framing full header
pkt.ip.src_addr = htonl(ipAddr); // inet address of given Interface
pkt.ip.dest_addr = inet_addr(argv[2]);// to whom shall we send

pkt.ip.checksum = htons(header_checksum( (char *)&pkt.ip.version_headerlen, 20));

// ICMP header
pkt.icmp.type = 0x08; // ICMP request
pkt.icmp.code = 0x00; // Code for ICMP request
pkt.icmp.checksum = htons(0x0000); // Will be filled after framing full header
pkt.icmp.ident = htons(0x0300); // anything
pkt.icmp.seq_no = htons(0xC000); // anything

pkt.icmp.checksum = htons(header_checksum( (char *)&pkt.icmp.type, 8));

// Data padding
memset(pkt.data, 0, 32 * sizeof(unsigned char));// Windows(R) Style

#ifndef DBG_ICMP
print_pkt((char *)&pkt, sizeof(pkt));
#endif

//======================Ok, Now send it!================

// We need this to send the packet
sa.sll_family = AF_PACKET; // AF_PACKET is a must
sa.sll_ifindex = ifr.ifr_ifindex; // chosen if. index number
sa.sll_protocol = htons(ETH_P_IP); // protocol of interest

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

return 0;
}

/***********************************************************
* To find the checksum of any header
* Description:
* - add two bytes at a time till the end
* - add the overflow till you come up with a 2-byte result
* - take a 1's compliment
***********************************************************/
unsigned short int header_checksum(char *buf, unsigned short int len)
{
unsigned char *header;

unsigned short int low16 = 0,i = 0;
unsigned long int checksum_32 =0;

// add 2 bytes at a time
for(i = 0; i < len; i+=2 )
{
low16 = (buf[i] << 8)&0xFF00 | buf[i+1]&0xFF ;
checksum_32 = checksum_32 + low16;
}

// Append the overflow -- 2 times for safety
if(checksum_32 >> 16)
{
checksum_32 = (checksum_32 & 0xFFFF) + (checksum_32 >> 16);
}
if(checksum_32 >> 16)
{
checksum_32 = (checksum_32 & 0xFFFF) + (checksum_32 >> 16);
}
// One's compliment
checksum_32 = ~checksum_32;

return (checksum_32&0xFFFF);
}

/**********************************************
* To Print the packet *
**********************************************/
int print_pkt( char *buf, unsigned short int len)
{
int i = 0;

printf("Size of packet = %d\n",len);
for( i = 0; i < len ; i++)
{
if(i%16 == 0)
printf("\n");

printf("%02x ",buf[i]&0xff);
}
printf("\n");
return 0;
}

Sunday, December 6, 2009

Reading routing table using C program

#include"sys/socket.h"
#include"sys/types.h"
#include"unistd.h"
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"asm/types.h"
#include"linux/netlink.h"
#include"linux/rtnetlink.h"
#include"sys/ioctl.h"
#include"net/if.h"
#include"net/route.h"

#pragma pack(2)
// Structure for sending the request
typedef struct
{
struct nlmsghdr nlMsgHdr;
struct rtmsg rtMsg;
char buf[1024];
}route_request;

// Structure for storing routes
struct RouteInfo
{
unsigned long dstAddr;
unsigned long mask;
unsigned long gateWay;
unsigned long flags;
unsigned long srcAddr;
unsigned char proto;
char ifName[IF_NAMESIZE];
};

// Function for accessing interface name
int ifname(int ,char *);

int main(int argc, char *argv[])
{
int route_sock,i,j;
route_request *request = (route_request *)malloc(sizeof(route_request));
int retValue = -1,nbytes = 0,reply_len = 0;
char reply_ptr[1024];
ssize_t counter = 1024;
int count =0;
struct rtmsg *rtp;
struct rtattr *rtap;
struct nlmsghdr *nlp;
int rtl;
struct RouteInfo route[24];
char* buf = reply_ptr;
unsigned long bufsize ;

if( argc > 1)
{
if(getuid() && geteuid())
{
printf("Oops!\n Need SuperUser rights!\n");
}
exit(1);
}

route_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

bzero(request,sizeof(route_request));

// Fill in the NETLINK header
request->nlMsgHdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
request->nlMsgHdr.nlmsg_type = RTM_GETROUTE;
request->nlMsgHdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;

// set the routing message header
request->rtMsg.rtm_family = AF_INET;
request->rtMsg.rtm_table = 254;

// Send routing request
if ((retValue = send(route_sock, request, sizeof(route_request), 0)) < 0)
{
perror("send");
exit(1);
}

for(;;)
{
if( counter < sizeof( struct nlmsghdr))
{
printf("Routing table is bigger than 1024\n");
exit(1);
}

nbytes = recv(route_sock, &reply_ptr[reply_len], counter, 0);

if(nbytes < 0 )
{
printf("Error in recv\n");
break;
}

if(nbytes == 0)
printf("EOF in netlink\n");

nlp = (struct nlmsghdr*)(&reply_ptr[reply_len]);

if (nlp->nlmsg_type == NLMSG_DONE)
{
// All data has been received.
// Truncate the reply to exclude this message,
// i.e. do not increase reply_len.
break;
}

if (nlp->nlmsg_type == NLMSG_ERROR)
{
printf("Error in msg\n");
exit(1);
}

reply_len += nbytes;
counter -= nbytes;
}

/*======================================================*/
bufsize = reply_len;
// string to hold content of the route
// table (i.e. one entry)
unsigned int flags;

// outer loop: loops thru all the NETLINK
// headers that also include the route entry
// header
nlp = (struct nlmsghdr *) buf;

for(i= -1; NLMSG_OK(nlp, bufsize); nlp=NLMSG_NEXT(nlp, bufsize))
{
// get route entry header
rtp = (struct rtmsg *) NLMSG_DATA(nlp);
// we are only concerned about the
// tableId route table
if(rtp->rtm_table != 254)
continue;
i++;
// init all the strings
bzero(&route[i], sizeof(struct RouteInfo));
flags = rtp->rtm_flags;
route[i].proto = rtp->rtm_protocol;

// inner loop: loop thru all the attributes of
// one route entry
rtap = (struct rtattr *) RTM_RTA(rtp);
rtl = RTM_PAYLOAD(nlp);
for( ; RTA_OK(rtap, rtl); rtap = RTA_NEXT(rtap, rtl))
{
switch(rtap->rta_type)
{
// destination IPv4 address
case RTA_DST:
count = 32 - rtp->rtm_dst_len;

route[i].dstAddr = *(unsigned long *) RTA_DATA(rtap);

route[i].mask = 0xffffffff;
for (; count!=0 ;count--)
route[i].mask = route[i].mask << 1;

//printf("dst:%s \tmask:0x%x \t",inet_ntoa(route[i].dstAddr), route[i].mask);
break;
case RTA_GATEWAY:
route[i].gateWay = *(unsigned long *) RTA_DATA(rtap);
//printf("gw:%s\t",inet_ntoa(route[i].gateWay));
break;
case RTA_PREFSRC:
route[i].srcAddr = *(unsigned long *) RTA_DATA(rtap);
//printf("src:%s\t", inet_ntoa(route[i].srcAddr));
break;
// unique ID associated with the network
// interface
case RTA_OIF:
ifname(*((int *) RTA_DATA(rtap)),route[i].ifName);
//printf( "ifname %s\n", route[i].ifName);
break;
default:
break;
}

}
//set Flags

//[TODO]: UP hardcoded?!
route[i].flags|=RTF_UP;
if (route[i].gateWay != 0)
route[i].flags|=RTF_GATEWAY;
if (route[i].mask == 0xFFFFFFFF)
route[i].flags|=RTF_HOST;
}

// Print the route records
printf("Destination\tGateway \tNetmask \tflags \tIfname \n");
printf("-----------\t------- \t--------\t------\t------ \n");
for( j = 0; j<= i; j++)
{
printf("%s \t0x%08x\t0x%08x \t%d \t%s\n",
inet_ntoa(route[j].dstAddr),
ntohl(route[j].gateWay),
route[j].mask,
route[j].flags,
route[j].ifName);
}
return 0;
}

/*--------------------------------------------------------------
* To get the name of the interface provided the interface index
*--------------------------------------------------------------*/
int ifname(int if_index,char *ifName)
{
int fd,retVal = -1;
struct sockaddr_in *sin;
struct ifreq ifr;


fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd == -1)
{
perror("socket");
exit(1);
}

ifr.ifr_ifindex = if_index;

if(ioctl(fd, SIOCGIFNAME, &ifr, sizeof(ifr)))
{
perror("ioctl");
exit(1);
}

strcpy(ifName, ifr.ifr_name);
return ;
}

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