lkml.org 
[lkml]   [2003]   [May]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectIP_HDRINCL and IP_PKTINFO on RAW sockets with sendmsg
From
Date
Hello,

I am using IP_HDRINCL and IP_PKTINFO (to choose by which interface the
packet leaves) on a RAW socket.

I'm using the udphdr structure with IPPROTO_RAW but I keep Malformed
Packet in the Ethereal traces and the IP header can't even be read by
Ethereal.

Is there something wrong with my approach? Please advise. Thank you.

Regards,
Se-Hsieng

Attached: test_iphdr.c


#include <sys/socket.h>
#include <sys/uio.h>
#include <unistd.h>
#include <resolv.h>
#include <net/if.h>
#include <netinet/udp.h>
#include <netinet/ip.h>

#define BUFFER_SIZE 36000

int main(void)
{
char *buffer;
int buffer_size = BUFFER_SIZE;
int s = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
struct sockaddr_in sin;
struct msghdr msg;
struct cmsghdr *cmsg;
struct in_pktinfo *pktinfo;
char outcmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
struct iovec io;
int yes=1;
int i, bytes;
char *interface="eth0";
struct ip *iph;
int iphdrSz;
struct udphdr* udph;
int if_index1=0;
int if_index2=0;

bzero(&sin, sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=INADDR_ANY;
sin.sin_port=htons(10000);
if (bind(s, (struct sockaddr *)&sin, sizeof(sin))<0) {
printf("bind: UH-OH.\n");
exit(1);
}

bzero(&sin,sizeof(sin));
bzero(&msg,sizeof(msg));

sin.sin_family=AF_INET;
sin.sin_port=htons(10000);
sin.sin_addr.s_addr=inet_addr("137.132.165.146");

msg.msg_name=&sin;
msg.msg_namelen=sizeof(sin);
msg.msg_control= outcmsg;
msg.msg_controllen=sizeof(outcmsg);
msg.msg_flags=0;

buffer=(char*)malloc(buffer_size);

if (setsockopt(s,SOL_IP,IP_HDRINCL,&yes,sizeof(yes))==0) {
printf("Construct IP header ok.\n");
}

/* Construct IP header */
iph=(struct ip*)buffer;
iph->ip_hl=5;
iph->ip_v=4;
iphdrSz=sizeof(struct ip);
iph->ip_len = htons(buffer_size+iphdrSz);
iph->ip_id=0;
iph->ip_off=0x40;
iph->ip_p=132;
iph->ip_sum=0;
iph->ip_src.s_addr=0;
iph->ip_dst.s_addr=0;

udph=(struct udphdr*) ((u_long)buffer+sizeof(struct ip));
udph->source=htons(10000);
udph->dest=htons(10000);
udph->len=htons(buffer_size);
udph->check=0;

io.iov_base=buffer;
io.iov_len=strlen(buffer);


if (setsockopt(s, SOL_IP, IP_PKTINFO,&yes,sizeof(yes))==0) {
printf("sok opt OK\n");
}

cmsg=CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level=SOL_IP;
cmsg->cmsg_type=IP_PKTINFO;
cmsg->cmsg_len=CMSG_LEN(sizeof(struct in_pktinfo));

msg.msg_controllen=cmsg->cmsg_len;
pktinfo=(struct in_pktinfo *)CMSG_DATA(cmsg);
memset(pktinfo, 0x00, sizeof(struct in_pktinfo));


msg.msg_iov=&io;
msg.msg_iovlen=1;


for (i=0;i<10;i++) {



if_index1 = if_nametoindex("eth0");

printf("eth0, %d\n", if_index1);

if (!if_index1) {
printf("Interface %s unknown\n", interface);
exit(1);
}



pktinfo->ipi_ifindex=if_index1;
//pktinfo->ipi_spec_dst.s_addr=inet_addr("137.132.53.46");
if ( (bytes=sendmsg(s,&msg,0))<0 ) printf("cannot send \n");

if_index2 = if_nametoindex("eth1");

printf("eth1, %d\n", if_index2);
if (!if_index2) {
printf("Interface %s unknown\n", interface);
exit(1);
}



pktinfo->ipi_ifindex=if_index2;

if ( (bytes=sendmsg(s,&msg,0))<0 ) printf("cannot send \n");


}

close (s);
free(buffer);


}
\
 
 \ /
  Last update: 2005-03-22 13:35    [W:0.042 / U:0.076 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site