[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-newbie
Subject: IP_HDRINCL and IP_PKTINFO on RAW sockets with sendmsg
From: Eng Se-Hsieng <g0202512 () nus ! edu ! sg>
Date: 2003-05-20 14:05:27
[Download RAW message or body]
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
["test_rawhdr.c" (test_rawhdr.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);
}
-
To unsubscribe from this list: send the line "unsubscribe linux-newbie" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.linux-learn.org/faqs
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic