C语言 sendto() :无效参数 - 原始套接字



我想使用原始套接字访问 ip 标头,更改 TTL 值并将数据包转发到客户端。服务器的地址是192.168.1.5,客户端的地址是192.168.1.3。我对 sendto() 函数有问题,错误处理打印输出:sendto() 失败:参数无效。我的代码在这里:

#include<netinet/in.h>
#include<errno.h>
#include<netdb.h>
#include<stdio.h> //For standard things
#include<stdlib.h>    //malloc
#include<string.h>    //strlen
#include<netinet/ip_icmp.h>   //Provides declarations for icmp header
#include<netinet/udp.h>   //Provides declarations for udp header
#include<netinet/tcp.h>   //Provides declarations for tcp header
#include<netinet/ip.h>    //Provides declarations for ip header
#include<netinet/if_ether.h>  //For ETH_P_ALL
#include<net/ethernet.h>  //For ether_header
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int soket;
soket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP));
if (soket<0)
{
    printf("Error creating socketn");
    return -1;
}
else 
    printf("Socket OKnn");
unsigned char *buffer = (unsigned char *) malloc(65536);
memset (buffer,0,65536);
struct sockaddr saddr;
struct sockaddr_in source,dest;
int saddr_len = sizeof (saddr);
int dest_len = sizeof (dest);
source.sin_family = AF_INET;
dest.sin_family = AF_INET;
// Port numbers
source.sin_port = htons(53);
dest.sin_port = htons(53);
// IP addresses
source.sin_addr.s_addr = inet_addr ("192.168.1.5");
dest.sin_addr.s_addr = inet_addr ("192.168.1.3");
setsockopt(soket, SOL_SOCKET , SO_BINDTODEVICE , "eth0" , strlen("eth0")+ 1 
);

if (bind(soket, (struct sockaddr*) &source, sizeof(source)) < 0) {
perror("bind failedn");
close(soket);
return -1;
}
if (recvfrom(soket,buffer,65536,0,(struct sockaddr *)&dest,&dest_len)<0)
{
    printf ("Paket nije primljenn");
    return -1;
}
else
    printf ("Paket je primljennn");
fflush (stdin);
//EXTRACTING THE IP HEADER
unsigned short iphdrlen;
struct iphdr *ip = (struct iphdr*)(buffer + sizeof(struct ethhdr));
memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = ip->saddr;
memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = ip->daddr;
printf ("Changing TTL:nn");
ip->ttl=0;
if(sendto(soket, &ip, sizeof (ip), 0, (struct sockaddr *)&dest, 
sizeof(dest)) < 0)
// Verify
{
perror("Error sendingn");
exit(-1);
}
else
{
printf("Sending OKn");
sleep(2);
} 
close(soket);
return 0;
}

这段代码和 sendto() 的参数有什么问题?请问谁能帮忙?

两个问题(如何称呼sendto()):

  1. 当您定义时

    struct iphdr *ip
    

    然后

    sizeof(ip)
    

    返回指针的大小。

    你想要的是调用sendto()struct iphdr的大小。

  2. 由于ip已经是一个指针,所以只需传递它,不要传递它的地址。


从文档中:

ssize_t sendto(int socket, const void *message, size_t length,
   int flags, const struct sockaddr *dest_addr,
   socklen_t dest_len);

消息

指向包含要发送的消息的缓冲区。

长度

指定消息的大小(以字节为单位)。


所以要修复此更改

  ... sendto(soket, &ip, sizeof (ip), ....

要成为

  ... sendto(soket, ip, sizeof (*ip), ....

或(相同)但更好,因为去掉无用的括号

  ... sendto(soket, ip, sizeof *ip, ....

相关内容

最新更新