c - 构建并发送 RAW 数据报

标签 c udp ipv4 packet-sniffers packets

您好,我想制作一个与“SendIP 发送任意 IP 数据包的命令行工具”类似的程序

我有一个程序可以发送“IPv4 + UDP”。我尝试通过 Wireshark 验证我的程序,但没有收到任何消息,我不知道为什么。

我通过命令发送./Project 192.168.1.15 21 192.168.1.15 8080 5

这是我的代码:(在 ipv4.h 和 udp.h 中,我有 ip 和 udp header )

#include <unistd.h>

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/ip.h>

#include <netinet/udp.h>
#include "ipv4.h"
#include "udp.h"

// Source IP, source port, target IP, target port from the command line arguments

int main(int argc, char *argv[])

{
    if (argc != 6)

    {

        printf("- Invalid parameters!!!\n");

        printf(
                "- Usage %s <source hostname/IP> <source port> <target hostname/IP> <target port>\n",
                argv[0]);

        exit(-1);

    }

    else {
        int sd;

        char buffer[PCKT_LEN];

        struct ipheader *ip = (struct ipheader *) buffer;

        struct udpheader *udp = (struct udpheader *) (buffer
                + sizeof(struct ipheader));

        // Source and destination addresses: IP and port

        struct sockaddr_in sin, din;

        int one = 1;

        const int *val = &one;

        memset(buffer, 0, PCKT_LEN);

        // Create a raw socket with UDP protocol

        sd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);

        if (sd < 0)

        {

            perror("socket() error");

            // If something wrong just exit

            exit(-1);

        }

        else

            printf(
                    "socket() - Using SOCK_RAW socket and UDP protocol is OK.\n");

        // The address family

        sin.sin_family = AF_INET;

        din.sin_family = AF_INET;

        // Port numbers

        sin.sin_port = htons(atoi(argv[2]));

        din.sin_port = htons(atoi(argv[4]));

        // IP addresses

        sin.sin_addr.s_addr = inet_addr(argv[1]);

        din.sin_addr.s_addr = inet_addr(argv[3]);

        ip->iph_ihl = 5;

        ip->iph_ver = 4;

        ip->iph_tos = 16; // Low delay

        ip->iph_len = sizeof(struct ipheader) + sizeof(struct udpheader);

        ip->iph_ident = htons(54321);

        ip->iph_ttl = 64; // hops

        ip->iph_protocol = 17; // UDP

        ip->iph_sourceip = inet_addr(argv[1]);

        // The destination IP address

        ip->iph_destip = inet_addr(argv[3]);

        // Fabricate the UDP header. Source port number, redundant

        udp->udph_srcport = htons(atoi(argv[2]));

        // Destination port number

        udp->udph_destport = htons(atoi(argv[4]));

        udp->udph_len = htons(sizeof(struct udpheader));

        // Calculate the checksum for integrity

        ip->iph_chksum = csum((unsigned short *) buffer,
                sizeof(struct ipheader) + sizeof(struct udpheader));

        if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)

        {

            perror("setsockopt() error");

            exit(-1);

        }

        else

            printf("setsockopt() is OK.\n");

        printf("Trying...\n");

        printf("Using raw socket and UDP protocol\n");

        printf("Using Source IP: %s port: %u, Target IP: %s port: %u.\n",
                argv[1], atoi(argv[2]), argv[3], atoi(argv[4]));

        //printf("Interfejs=%d\n", *val);

        int count;
        int number = (atoi(argv[5]));
        printf("Number=%d\n", number);
        for (count = 1; count <= number; count++)

        {

            if (sendto(sd, buffer, ip->iph_len, 0, (struct sockaddr *) &sin,
                    sizeof(sin)) < 0)

            {

                perror("sendto() error");

                exit(-1);

            }

            else

            {

                printf("Count #%u - sendto() is OK.\n", count);

                sleep(2);

            }

        }

        close(sd);

        return 0;
    }
}

最佳答案

好的,我修复它。问题在于 int one = 1;具体有哪些接口(interface)。我改成0就可以了。多么愚蠢的错误啊:Dp>

关于c - 构建并发送 RAW 数据报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47058897/

相关文章:

python - 为什么 gethostbyaddr(gethostname()) 返回我的 IPv6 IP?

php - 是否可以将 getaddrinfo() 设置为默认仅检索 IPV4 地址?

c - 在C中读取不同数量的参数

c - 如何保证变量的大小

c# - 在 Udp 级别 :"Only one usage of each socket address is normally permitted"

sockets - 为什么UDP套接字是通过目的IP地址和目的端口来识别的?

c - 当循环跳过用户输入时,我做错了什么?

c# - 面向对象的概念适用于C语言吗?

qt - 将IplImage转换为QByteArray

java - 用于验证 InetSocketAddresses(ipv4/v6 + 端口地址)的正则表达式