【问题标题】:C - create TCP SYN without filling IP header using raw socketC - 创建 TCP SYN 而不使用原始套接字填充 IP 标头
【发布时间】:2016-03-29 18:13:34
【问题描述】:

我希望我的应用程序创建 TCP SYN 数据包并在网络上发送。我没有使用setsockopt 设置IP_HDRINCL,因为我希望内核填充IP Header。

我试过了

  1. 使用字节缓冲区包含 TCP Header + Payload
  2. 使用字节缓冲区包含 IP 标头 + TCP 标头 + 有效负载。

以上两个方法都返回了sendto错误-1并且errno设置为88 以下是我使用的代码

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <errno.h>

int main()
{
    int sockfd;

    if(sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP) < 0)
    {
        printf("sokcet functin failed : \n");
        exit (-1);
    }

    char packet[512];

    struct sockaddr_in remote; // remote address

    struct iphdr *ip = (struct iphdr *) packet;
    struct tcphdr *tcp = (struct tcphdr *) packet + sizeof(struct iphdr);


    /*
    struct tcphdr *tcp = (struct tcphdr *) packet; // tcp header
    */
    remote.sin_family = AF_INET; // family
    remote.sin_addr.s_addr = inet_addr("192.168.0.57"); // destination ip
    remote.sin_port = htons(atoi("3868")); // destination port

    memset(packet, 0, 512); // set packet to 0

    tcp->source = htons(atoi("6668")); // source port
    tcp->dest = htons(atoi("3868")); // destination port
    tcp->seq = htons(random()); // inital sequence number
    tcp->ack_seq = htons(0); // acknowledgement number
    tcp->ack = 0; // acknowledgement flag
    tcp->syn = 1; // synchronize flag
    tcp->rst = 0; // reset flag
    tcp->psh = 0; // push flag
    tcp->fin = 0; // finish flag
    tcp->urg = 0; // urgent flag
    tcp->check = 0; // tcp checksum
    tcp->doff = 5; // data offset

    int err;
    if((err = sendto(sockfd, packet, sizeof(struct iphdr), 0, (struct sockaddr *)&remote, sizeof(struct sockaddr))) < 0)
    { // send packet
        printf("Error: Can't send packet : %d %d !\n\n", err, errno);
        return -1;
    }

为什么我收到 sendto 错误 -1 和 errno 88?

另外,我想知道如何确定在sendto 函数的第二个参数中使用的数据长度。如果我将其硬编码为数据包字节缓冲区的大小,即 512 字节,是不是错了?

【问题讨论】:

  • "谁能帮助我了解 sendto 错误背后的原因?"不,但你可以帮助自己。根据文档检查errno,以确定问题的原因。确保你在a human readable form!
  • 编辑了我的问题
  • “errno 88”没有帮助。 sendto 返回 -1 只是表明它失败了。如果您按照平台上的文档进行操作,您会注意到您必须检查errno 以检查错误原因,并且您可以使用strerror 将“errno 88”翻译成英文。这样做。
  • strerror(errno) 导致分段错误。

标签: c linux raw-sockets


【解决方案1】:

这里我不是给出解决方案,而是 你可以检查你的错误的含义,可以纠正你的错误,我也不能发表评论,因为我没有太多的声誉..我只是想帮忙......

int err = sendto(sockfd, packet, sizeof(struct iphdr), 0, (struct sockaddr *)&remote, sizeof(struct sockaddr)));
int saved_error = errno;  // Save errno flag that is set by sendto.
if(err < 0) {
    fprintf(stderr, "Send Error: %s\n", strerror(saved_error));
}

我认为这可能会有所帮助...但这不是答案...这将给出错误的含义,以便您可以纠正错误..

【讨论】:

  • @subhu 不能,因为这段代码要么成功要么输出“Send Error: ...”,其中...是英文文本。
【解决方案2】:

对于 SOCK_RAW,您可以使用 AF_ATMPVC:访问原始 ATM PVC

在您的代码中:

if((sockfd = socket(AF_ATMPVC, SOCK_RAW, IPPROTO_TCP)) < 0)

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多