i want to detect ip options of incoming internet packets. Here's my code.
//#define IPPROTO_IP 0
//#define IP_OPTIONS 68
#define SENDER_PORT_NUM 53
#define SENDER_IP_ADDR "127.0.0.1"
#define true 1
static void bail(const char *error)
{
printf("%s: %s\n", error, strerror(errno));
exit(1);
}
struct ip_datagram{
unsigned char ver_ihl;
unsigned char tos;
unsigned short totlen;
unsigned short id;
unsigned short flags_offs;
unsigned char ttl;
unsigned char proto;
unsigned short checksum;
unsigned long src;
unsigned long dst;
unsigned char payload[1500];
};
int main(){
int s,b,sso,gso, i;
int contatore = 5;
int enabled = 1;
char *data, *buffer;
int addrlen;
struct sockaddr_in addr;
struct ip_datagram *ip, *ip_reply;
struct icmphdr* icmp;
//char *src_addr="93.34.229.111";
char *dst_addr="127.0.0.1";
data = malloc(sizeof(struct ip_datagram)+ sizeof(struct icmphdr));
buffer = malloc(sizeof(struct ip_datagram)+ sizeof(struct icmphdr));
ip = (struct ip_datagram *) (data );
icmp = (struct icmphdr*) (data + sizeof(struct ip_datagram));
ip->ver_ihl = 45;
//ip->ihl = 15;
ip->totlen = sizeof(struct ip_datagram);
ip->proto = IPPROTO_ICMP;
//ip->src =(inet_addr(src_addr));
ip->dst = inet_addr(dst_addr);
ip->checksum = in_cksum((unsigned short *)ip, sizeof(struct ip_datagram));
icmp->type = ICMP_ECHO;
icmp->checksum = in_cksum((unsigned short *)icmp, sizeof(struct icmphdr));
s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if(s<0)
printf("errore socket\n");
sso = setsockopt(s, IPPROTO_IP, IP_OPTIONS, &enabled, sizeof(enabled));
if(sso<0)
bail("errore setsockoptions\n");
gso = (s, IPPROTO_IP, IP_OPTIONS, &enabled, sizeof(enabled));
if(gso<0)
bail("errore getsockoptions\n");
else
printf("IP_OPTIONS VALUE :%d\n", enabled);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = ip->dst;
while(contatore>0){
int sent_bytes = sendto(s, (const char *)data, ip->totlen, 0, (struct sockaddr*)&addr, sizeof(struct sockaddr) );
if(sent_bytes <0){
printf("failed to send packets\n");
return 3;
}
//printf("Sent %d byte packet from %s to %s\n", ip->totlen, src_addr, dst_addr);
printf("Sent %d byte packet to %s\n", ip->totlen, dst_addr);
addrlen = sizeof(addr);
int bytes = recvfrom(s, buffer, sizeof(struct ip_datagram) + sizeof(struct icmphdr), 0, (struct sockaddr*)&addr, &addrlen);
if(bytes<=0){
printf("errore recvfrom\n");
break;
}
else{
char *cp;
ip_reply = (struct ip_datagram*) buffer;
cp = (char *)&ip_reply->src;
printf("Received %d byte reply from %u.%u.%u.%u:\n", ntohs(ip_reply->totlen), cp[0]&0xff,cp[1]&0xff,cp[2]&0xff,cp[3]&0xff);
printf("ID: %d\n", ntohs(ip_reply->id));
printf("TTL: %d\n", ip_reply->ttl);
printf("type of service: %.1X\n", ip_reply->tos);
printf("IP ADDRESS SOURCE: %.4X\n", htonl(ip_reply->src));
printf("IP ADDRESS DESTINATION: %.4X\n", htonl(ip_reply->dst));
printf("versione + header length: %.1X\n", ip_reply->ver_ihl);
contatore--;
printf("-----------------\n");
printf("****************\n");
}
}
}
the problem is the header length is 6 but the length should be 20 for detecting all ip options. In setsockopt, maybe, the type of enabled variable should be a char, but i have some problem when i run the program: in fact, with a char type it gives me an error for invalid argument. I want to know also how to print these options using getsockoption. What's the problem? i hope my question is clear :)
The structure you define for your IP header MIGHT be broadly compatible with an IP packet header but it's not really good enough and not easily usable.
On my Linux system the system headers define the IP header in /usr/include/linux/ip.h like this:
As you can see, this breaks the IP version and header length properly, and it's safer to be compiled for big or little endian targets.
With a structure definition like this you can find the start of the IP options after
sizeof(struct iphdr)
bytes, and the size of the entire IP header will beip.ihl * 4
, where ip is astruct iphdr
.You need the multiplication by 4 above because
ihl
is the number of 32 bit words that makes up the IP header, not the byte count of the header itself.You can look at IPv4 (Wikipedia) which has some general information about IP header options and their format, and IANAs list of IP Options for a complete list, with links to the various RFCs which describe the details of each option.