构建并发送RAW数据报

时间:2017-11-01 15:58:29

标签: 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头文件)

#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;
    }
}

1 个答案:

答案 0 :(得分:0)

好的,我解决了。问题是int one = 1;其中specife的接口数量。我改为0,它的工作原理。多么愚蠢的错误:D