设置检测ip选项的setsockopt

设置检测ip选项的setsockopt,c,networking,ip,setsockopt,getsockopt,C,Networking,Ip,Setsockopt,Getsockopt,我想检测传入internet数据包的ip选项。这是我的密码 //#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

我想检测传入internet数据包的ip选项。这是我的密码

//#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");
      }
   }    
}
/#定义IP协议IP 0
//#定义IP_选项68
#定义发送方\端口\数量53
#定义发送方IP地址“127.0.0.1”
#定义真1
静态无效保释(常量字符*错误)
{
printf(“%s:%s\n”,错误,strerror(errno));
出口(1);
}
结构ip_数据报{
未签名字符版本ihl;
无符号字符;
无符号短totlen;
无符号短id;
未签名的短标志;
无符号字符ttl;
无符号字符原型;
无符号短校验和;
无符号长src;
无符号长dst;
无符号字符有效载荷[1500];
};       
int main(){
int s,b,sso,gso,i;
int contatore=5;
int enabled=1;
字符*数据,*缓冲区;
int addrlen;
地址中的结构sockaddr\u;
结构ip_数据报*ip,*ip_回复;
结构icmphdr*icmp;
//char*src_addr=“93.34.229.111”;
char*dst_addr=“127.0.0.1”;
数据=malloc(sizeof(struct ip_数据报)+sizeof(struct icmphdr));
buffer=malloc(sizeof(struct ip_数据报)+sizeof(struct icmphdr));
ip=(结构ip_数据报*)(数据);
icmp=(结构icmphdr*)(数据+sizeof(结构ip_数据报));
ip->ver_ihl=45;
//ip->ihl=15;
ip->totlen=sizeof(结构ip_数据报);
ip->proto=IPPROTO_ICMP;
//ip->src=(inet_addr(src_addr));
ip->dst=inet_addr(dst_addr);
ip->checksum=in_cksum((无符号短*)ip,sizeof(结构ip_数据报));
icmp->type=icmp\u ECHO;
icmp->checksum=in_cksum((无符号短*)icmp,sizeof(struct icmphdr));
s=插座(AF_INET、SOCK_RAW、IPPROTO_ICMP);
if(stotlen,0,(struct sockaddr*)&addr,sizeof(struct sockaddr));
if(发送字节至总字节、src地址、dst地址);
printf(“已将%d字节数据包发送到%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);
如果(b),;
printf(“收到来自%u.%u.%u.%u:\n的%d字节回复”,ntohs(ip_回复->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\U应答->TTL);
printf(“服务类型:%.1X\n”,ip\U应答->tos);
printf(“IP地址源:%.4X\n”,htonl(IP_reply->src));
printf(“IP地址目的地:%.4X\n”,htonl(IP_应答->dst));
printf(“版本号+标题长度:%.1X\n”,ip\U应答->版本号ihl);
康塔托雷--;
printf(“--------------\n”);
printf(“******************\n”);
}
}    
}

问题是头的长度是6,但检测所有ip选项的长度应该是20。在setsockopt中,可能启用变量的类型应该是字符,但我在运行程序时遇到了一些问题:事实上,对于字符类型,它会给我一个无效参数的错误。我还想知道如何使用getsockopti打印这些选项问题是什么?我希望我的问题是清楚的:)

您为IP报头定义的结构可能与IP数据包报头广泛兼容,但它还不够好,不容易使用

在我的Linux系统上,系统头在/usr/include/Linux/IP.h中定义IP头,如下所示:

struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8    ihl:4,
            version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
    __u8    version:4,
            ihl:4;
#else
#error  "Please fix <asm/byteorder.h>"
#endif
    __u8    tos;
    __be16  tot_len;
    __be16  id;
    __be16  frag_off;
    __u8    ttl;
    __u8    protocol;
    __sum16 check;
    __be32  saddr;
    __be32  daddr;
    /*The options start here. */
};
struct iphdr{
#如果已定义(uuu LITTLE_ENDIAN_位字段)
__u8国际人道主义法:4,
版本:4;
#elif已定义(_BIG_ENDIAN_位域)
__u8版本:4,
国际人道主义法:4;
#否则

#错误"请修复其中包含有关IP头选项及其格式的一些一般信息,并获得完整列表,以及描述每个选项详细信息的各种RFC的链接。

请正确缩进您的代码,以便更易于阅读。如何处理IP版本和合并成单个字节的头长度需要将它们拆分为4位的数量,这样它们才有用。好的,我做了更改。现在标头长度是24,我如何看到ip选项?setsockopt seeting可以检测这些选项?好的,这意味着你有4个字节的ip选项。不,getsockopt/setsockopt是套接字,与ip标头选项无关。我添加了一个段落在我的答案的底部有一些链接,这些链接指向一些关于IP头选项的页面,但是我担心你将不得不处理这些数据,我认为没有一个简单的库适合你。