Building IP header

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I want to build a packet with a source IP address and dest ip address (
usual case ) given by me and the protocol field in the IP hdr is a
unassigned protocol number ( i used 140 ).  I built the IP header by
opening a RAW socket and by setting the IP_HDRINCL option. The source IP
address i gave is not the IP address in any of the interfaces of my
machine. ( I gave 1.2.3.4 ). I bind the raw socket to a local interface
( my ip address is 192.168.100.242 ) and sent the packet using sendto.

Now in my same machine, i did another program to collect and display the
packet sent my me to my interface itself. This program will also open a
ra socket with protocol field as IPPROTO_RAW and i used recvfrom to
receive the message. But i am not receiving the message. I am missing
somewhere. I could not figure it out. I pasted the code here. Kindly
have a look into it and tell me where am missing. I will be very much
thankful. here is the code.

=====================================================
This program is the one am building the IP packet.
====================================================
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <errno.h>


#define PORT 0
#define PROTOCOL 140
#define LOCAL_IP_ADDR "192.168.100.242"
#define DEST_IP_ADDR "192.168.100.242"

#define MESSAGE "This is the packet from 1.2.3.4 IP address"  /*this
message is encapsulated by my IP hdr */

extern uint16_t checksum(uint16_t *,uint32_t );
extern int build_iphdr(void *,uint32_t );

main() {


int raw,sockopt_val=1;
struct sockaddr_in local_addr,peer_addr;
struct iphdr *ip;
char *my_sending_pkt;

if( (raw=socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0 ) {
perror("sock");
exit(1);
}

if( (my_sending_pkt=(char *)malloc(sizeof(struct iphdr)+sizeof(MESSAGE))
) == NULL ) {
 perror("Calloc failed:");
 exit(1);
}

ip=(struct iphdr *)my_sending_pkt;

strcpy( (my_sending_pkt+sizeof(struct iphdr)),MESSAGE);


bzero(&local_addr,sizeof(local_addr));
bzero(&peer_addr,sizeof(peer_addr));

local_addr.sin_family=AF_INET;
local_addr.sin_port=htons(PORT);

peer_addr.sin_family=AF_INET;
peer_addr.sin_port=htons(PORT);


if( (inet_aton(LOCAL_IP_ADDR,&local_addr.sin_addr.s_addr)) == 0 ) {
 perror("Addr conversion:");
 exit(1);
}

if( (inet_aton(DEST_IP_ADDR,&peer_addr.sin_addr.s_addr)) == 0 ) {
 perror("Addr conversion:");
 exit(1);
}

if( (setsockopt(raw,SOL_IP,IP_HDRINCL,&sockopt_val,(socklen_t
)sizeof(sockopt_val)) ) < 0 ) {
 perror("setsockopt:");
 exit(errno);
}

if( (build_iphdr(ip,sizeof(MESSAGE)) ) < 0 ) {
 perror("Build IP failed:");
 exit(1);
}


if( ( bind(raw,(struct sockaddr *)&local_addr,(socklen_t
)sizeof(local_addr)) ) < 0 ) {
 perror("Bind:");
 exit(1);
}


if( (sendto(raw,my_sending_pkt, (sizeof(struct
iphdr)+sizeof(MESSAGE)),0,(struct sockaddr *)&peer_addr
  ,(socklen_t)sizeof(peer_addr)) ) < 0 ) {

 perror("Sendto failed:");
 exit(1);
}


}

======================================================
The following code contains the api's build_iphdr and Checksum.
====================================================

/* this file contains the functions used for building IP packets */

#include <netinet/ip.h>
#include <netinet/in.h>
/*#include "lmptypes.h"*/ /* My hdr where the data types are type
defined */

/* #define SIZE 22   Since i am going to send the message "this is
1.2.3.4 packet"  */

#define SOURCE_IP "1.2.3.4"
#define DEST_IP "192.168.100.242"

uint16_t checksum(uint16_t *data,uint32_t len) {

/* data is the one for which we are calculating checksum and its size
len in bytes */

register uint32_t sum=0;
uint16_t ans;
register uint16_t *temp=data;
register uint32_t odd = len;

/* adding 16 bits every time to sum */
while( odd > 1) {
 sum += *temp;
 odd -= 2;
}

/* if length is odd the last 8 bits will also get added here */
if( odd )
 sum += *(uint8_t *)temp;

sum=(sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
ans=~sum; /* truncating to 16 bits */
return (ans);

}



int build_iphdr(void *buffer, uint32_t len) {

/* Pointer to the allocated buffer for IP hdr structure. len is the
length if the data to be encap in IP */
/* In this fn the tot length field is data len + ip hdr length */
/* id will be the current user id running the process */


struct iphdr *ip=buffer;

/*
if( (ip=(struct iphdr *)calloc(1,sizeof(struct iphdr)) ) == NULL ) {
 perror("calloc failed:");
 return -1;
}
*/

ip->version=4;
ip->ihl=5;
ip->tos=0;
ip->tot_len=sizeof(struct iphdr) + len;
ip->id=htons(getuid());
ip->ttl=255;
ip->protocol=htons(140);   /*My protocol number to check LMP */
if( (ip->saddr=inet_addr(SOURCE_IP)) < 0 ) {
 perror("Give valid source IP:");
 return -1;
}

if( (ip->daddr=inet_addr(DEST_IP)) < 0 ) {
 perror("Give valid dest IP:");
 return -1;
}

ip->check=checksum((unsigned short *)ip,sizeof(struct iphdr));

return 0;

}
=======================================================
The following is the code which is waiting to receive  the IP packet
what i sent. The display api will display the content of the packet and
i want to
see the IP address 1.2.3.4 here. But its not receiving the packet

=======================================================

#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>


void display(void *buf, int bytes)
{ int i;
 struct iphdr *ip = buf;


 printf("----------------\n");
 for ( i = 0; i < bytes; i++ )
 {
  if ( !(i & 15) ) printf("\n%04X:  ", i);
  printf("%02X ", ((unsigned char*)buf)[i]);
 }
 printf("\n");
 printf("IPv%d: hdr-size=%d pkt-size=%d protocol=%d TTL=%d src=%s ",
  ip->version, ip->ihl*4, ntohs(ip->tot_len), ip->protocol,
  ip->ttl, inet_ntoa(ip->saddr));
 printf("dst=%s\n", inet_ntoa(ip->daddr));
}

main()
{ int sd,sock_opt=1;
 struct sockaddr_in addr;
 unsigned char buf[1024];

 sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
 if ( sd < 0 )
 {
  perror("socket");
  exit(0);
 }


 if( fcntl(sd,F_SETFL,O_NONBLOCK) != 0 ) {
  perror("NON block IO fail:");
  exit(1);
 }
 for (;;)
 { int bytes, len=sizeof(addr);

  bzero(buf, sizeof(buf));
  bytes = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&addr,
&len);
  if ( bytes > 0 )
   display(buf, bytes);
 }
 exit(0);
}
======================================================

Kindly help me where am missing.

Thanks
Ramesh

-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux