Netcat没有收到udp制作的数据包

问题描述 投票:1回答:1

GOAL:从127.0.0.1 pport 8090向localhost端口8091发送精心制作的udp数据包。从[wireshark]可以看到,问题:下面显示的代码实际上可以正常显示我的数据包,其中包含我选择的值。无论如何,如果在终端A上执行nc -ulp 8091 -vv,而在终端B上执行程序,则什么也没有发生。我认为字符串“ hhhhhhhhhh”应该在输出中可见。问题:为什么我看不到程序发送的输出?

#include <sys/socket.h>
#include <linux/if_packet.h>
#include <net/ethernet.h> /* the L2 protocols */
#include <netinet/ip.h> 
#include <netinet/udp.h> 
#include <stdio.h>
#include <arpa/inet.h> /* htons */
#include <sys/ioctl.h> 
#include <net/if.h> /* ifreq */
#include <string.h> 
#include <stdlib.h>

#include <linux/seccomp.h> /* seccomp_data */

#define BUF_SIZE 2048 

//http://www.microhowto.info/howto/calculate_an_internet_protocol_checksum_in_c.html#idp22656
uint16_t ip_checksum(void* vdata,size_t length) {
    // Cast the data pointer to one that can be indexed.
    char* data=(char*)vdata;

    // Initialise the accumulator.
    uint32_t acc=0xffff;

    // Handle complete 16-bit blocks.
    for (size_t i=0;i+1<length;i+=2) {
        uint16_t word;
        memcpy(&word,data+i,2);
        acc+=ntohs(word);
        if (acc>0xffff) {
            acc-=0xffff;
        }
    }

    // Handle any partial block at the end of the data.
    if (length&1) {
        uint16_t word=0;
        memcpy(&word,data+length-1,1);
        acc+=ntohs(word);
        if (acc>0xffff) {
            acc-=0xffff;
        }
    }

    // Return the checksum in network byte order.
    return htons(~acc);
}

int main(){

    const char IF[] = "lo"; // modify to change interface
    int sockfd, ifindex, tx_len=sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct udphdr);
    struct ifreq ifr;
    size_t if_name_len;
    char packet[BUF_SIZE];
    struct ether_header *eh;
    struct iphdr *iph;
    struct udphdr *udph; 
    unsigned char *data;
    u_int16_t src_port, dst_port;
    struct sockaddr_ll dst_addr;
    struct seccomp_data sec_payload;
    const char dmac[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
    const char smac[] = {0x00, 0xd0, 0x56, 0xf2, 0xb5, 0x12};

    memset(packet, 0, sizeof(packet));
    eh = (struct ether_header *) packet;
    iph = (struct iphdr *) (packet + sizeof(struct ether_header));
        udph = (struct udphdr *) (packet + sizeof(struct ether_header) + sizeof(struct iphdr));
    data = (char *)packet + sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct udphdr);


    // create raw socket to send/receive ethernet frames that can transport all protocols
    if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
        perror("socket");
    }

    // get interface name length
    if_name_len = strlen(IF);
    if(if_name_len < IF_NAMESIZE) {
        strncpy(ifr.ifr_name, IF, strlen(IF));
        ifr.ifr_name[if_name_len]=0;
    }

    // get the interface index number
    if(ioctl(sockfd, SIOCGIFINDEX, &ifr) == -1){
        perror("ioctl");
    }
        ifindex = ifr.ifr_ifindex;

    // build ethernet header    
        memcpy(eh->ether_dhost, dmac, ETHER_ADDR_LEN);  
        memcpy(eh->ether_shost, smac, ETHER_ADDR_LEN);  
    eh->ether_type = htons(ETH_P_IP);

    // add a struct seccomp_data as data 

    strcpy(data, "hhhhhhhhh");
    tx_len += strlen(data);

    // build ip header
    iph->ihl = 5;
    iph->version = 4;
    iph->tos = 0;
    iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + strlen(data)); //sizeof(sec_payload)); //20+8+64
    iph->id = htons(54321);
    iph->frag_off = 0x00;
    iph->ttl = 0xFF;
    iph->protocol = IPPROTO_UDP;
    iph->check = 0;
    iph->saddr = inet_addr("127.0.0.1");
    iph->daddr = inet_addr("127.0.0.1");
    iph->check = ip_checksum(iph, iph->ihl << 2); 

    // build udp header 
    udph->source = htons(8090);
    udph->dest = htons(8091);
    udph->len = htons(sizeof(struct udphdr) + strlen(data));//sizeof(sec_payload));
    udph->check = 0;

    memset(&dst_addr, 0, sizeof(struct sockaddr_ll));   
    dst_addr.sll_ifindex = ifr.ifr_ifindex; 
    dst_addr.sll_halen = ETH_ALEN;
    memcpy(dst_addr.sll_addr, dmac, ETH_ALEN);

        if (sendto(sockfd, packet, tx_len, 0, (struct sockaddr*)&dst_addr, sizeof(struct sockaddr_ll)) < 0)
        printf("Send failed\n");
    return 0;
}
c networking udp packet netcat
1个回答
0
投票

您使用了相同的源IP地址和目标IP地址。只需将源地址更改为伪地址即可。 Linux内核必须丢弃该数据包,因为它认为它不是由它发出的。

© www.soinside.com 2019 - 2024. All rights reserved.