私は生のソケットを研究しています。IP_HDRINCL オプションを使用して、独自の IP ヘッダーを作成しました。IP ヘッダーの後に、UDP ヘッダーを作成しています。次に、システムのループバック アドレスにパケットを送信しています。UDP パケットが来るとそれをキャッチする別のプログラムを実行しています。パケットが正しく形成され、受信されているかどうかを確認するために、生の IP データグラムを読み取る別のプロセスを実行しています。私の問題は、2 番目のプロセス (生データグラムの読み取り) は正常に機能していますが (すべての IP フィールドと UDP フィールドは問題ないようです)、最初のプロセス (UDP の受信) が作成したパケットをまったく受信していないことです。IP ヘッダーのプロトコル フィールドは問題なく、ポートも一致しています... Linux 2.6.35-22 を使用しています。これが新しいカーネルで正常かどうか知りたいですか? バグがないか、以下のコードを確認してください。
unsigned short in_cksum(unsigned short *addr, int len)
{
int nleft = len;
int sum = 0;
unsigned short *w = addr;
unsigned short answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(unsigned char *) (&answer) = *(unsigned char *) w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
main()
{
int fd=socket(AF_INET,SOCK_RAW,IPPROTO_UDP);
int val=1;
int ret=setsockopt(fd,IPPROTO_IP,IP_HDRINCL,&val,sizeof(val));
char buf[8192];
/* create a IP header */
struct iphdr* ip=(struct iphdr*)buf;//(struct iphdr*) malloc(sizeof(struct iphdr));
ip->version=4;
ip->ihl=5;
ip->tos=0;
ip->id=0;
ip->frag_off=0;
ip->ttl=255;
ip->protocol=IPPROTO_UDP;
ip->check=0;
ip->saddr=inet_addr("1.2.3.4");
ip->daddr=inet_addr("127.0.0.1");
struct udphdr* udp=(struct udphdr*)(buf+sizeof(struct iphdr));//(struct udphdr*) malloc(sizeof(struct udphdr));
udp->source=htons(40000);
udp->dest=htons(50000);
udp->check=0;
char* data=(char*)buf+sizeof(struct iphdr)+sizeof(struct udphdr);strcpy(data,"Harry Potter and the Philosopher's Stone");
udp->len=htons(sizeof(struct udphdr)+strlen(data));
udp->check=in_cksum((unsigned short*) udp,8+strlen(data));
ip->tot_len=htons(sizeof(struct iphdr)+sizeof(struct udphdr)+strlen(data));
struct sockaddr_in d;
bzero(&d,sizeof(d));
d.sin_family=AF_INET;
d.sin_port=htons(50000);
inet_pton(AF_INET,"localhost",&d.sin_addr.s_addr);
while(1)
sendto(fd,buf,sizeof(struct iphdr)+sizeof(struct udphdr)+strlen(data),0,(struct sockaddr*) &d,sizeof(d));
}