我的问题与IP_HDRINCL
中setsockopt
标志的使用有关。我正在尝试使用原始套接字测试自定义协议的使用。我不确定我在做什么是否正确。我只是想将字符串以及客户端代码附加的ip标头传递给服务器代码。我写的第一个代码是:
Server.c
#include "../cn.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
int main(int argc, char const *argv[])
{
int rsfd = socket(AF_INET,SOCK_RAW,253);
if(rsfd<0)
{
perror("Could not create socket");exit(0);
}
int val = 1;
setsockopt(rsfd,IPPROTO_IP,SO_BROADCAST|IP_HDRINCL,&val,sizeof(val));
char buffer[100];
struct iphdr *ip;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.2");
if(bind(rsfd,(struct sockaddr*)&addr,sizeof(addr))<0)
{
perror("Could not bind");exit(0);
}
else
printf("Bound..\n");
if(recvfrom(rsfd,buffer,100,0,NULL,NULL)<0)
{
perror("Could not receive");exit(0);
}
else
{
printf("Success..\n");
ip = (struct iphdr*)(buffer);
char ad[INET_ADDRSTRLEN];
printf("Protocol No: %d\nTTL: %d\nVersion No: %d\nPacket ID: %d\nSource Address: %s\nChecksum: %d\nLength: %d\n",(int)ip->protocol,(int)ip->ttl,(int)ip->version,(int)ip->id,inet_ntop(AF_INET,&(ip->saddr),ad,INET_ADDRSTRLEN),(int)ip->check,(int)ip->ihl);
}
return 0;
}
Client.c
#include "../cn.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
int main(int argc, char const *argv[])
{
int rsfd = socket(AF_INET,SOCK_RAW,253);
if(rsfd<0)
{
perror("Could not create socket");exit(0);
}
int val = 1;
setsockopt(rsfd,IPPROTO_IP,SO_BROADCAST|IP_HDRINCL,&val,sizeof(val));
char buffer[100];
struct iphdr* ip;
ip = (struct iphdr*)buffer;
ip->protocol = 253;
ip->version = 4;
ip->id = 0;
ip->saddr = 0;
ip->daddr = inet_addr("127.0.0.2");
printf("Enter a string..\n");
scanf("%s",buffer+60); //trying to insert a string at buffer+60 position
printf("Entered: %s\n",buffer+60);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.2");
if(sendto(rsfd,buffer,100,0,(struct sockaddr*)&addr,sizeof(addr))<0)
perror("Could not send");
else
printf("Sent successfully..\n");
return 0;
}
程序正在运行,没有任何错误,但是当我尝试在偏移量60处打印消息时,它清除了一些垃圾值。然后,我尝试打印该字符缓冲区中的所有值,但令我惊讶的是,实际消息的偏移量为80,这意味着距插入位置正好20个字节。经过更多实验后,我意识到在服务器端收到的ip
头根本不是用户定义的头。网络层本身正在吸引它!但是IP_HDRINCL
选项是否应该保留附加IP标头的网络层?我说的是根据我对this的解释。 我在哪里做错了?另外,任何人都可以在原始套接字上提供一些好的教程(尤其是有关自定义协议实现的教程)吗?