精华内容
下载资源
问答
  • ping发送超大数据包(高级用法)

    千次阅读 2021-06-09 11:06:02
    ping -l 65500 -t node1

    在这里插入图片描述

    ping -l 65500 -t node1
    

    在这里插入图片描述

    展开全文
  • 如何基于 UDP 实现大数据包发送? 在 IP 协议中,存在以首部报文: 16 位标识:用来标识哪个包是同一个包拆分出来的; 3 位标志:通过这个片偏移来区分拆出来的包的顺序。即谁在前谁在后; 13 位片偏移:识别当前拆...

    如何基于 UDP 实现大数据包发送?

    在 IP 协议中,存在以首部报文:

    1. 16 位标识:用来标识哪些包是同一个包拆分出来的;
    2. 3 位标志:通过这个片偏移来区分拆出来的包的顺序。即谁在前谁在后;
    3. 13 位片偏移:识别当前拆出来的包是否是最后一个包,如果标志位为 0,则标志着到达最后一个分片。类似于链表用 null 来表示结束标志。

    根据这三个报文,IP 协议可以实现大数据包的分包。因此我们可以在应用层中实现这三个功能,然后使用 UDP 协议传输,即可实现大数据包的发送。

    展开全文
  • 作者:Godbach日期:2009/09/01一、构造数据包简析这里并不详细介绍如何在内核中构造数据包,下文如有需要会在适当的位置进行分析。这里简单的分析讲一下内核态基于Netfilter框架构造数据包的方式。内核中可以用到的...

    本文欢迎自由转载,但请标明出处,并保证本文的完整性。

    作者:Godbach

    日期:2009/09/01

    一、构造数据包简析

    这里并不详细介绍如何在内核中构造数据包,下文如有需要会在适当的位置进行分析。这里简单的分析讲一下内核态基于Netfilter框架构造数据包的方式。

    内核中可以用到的构造数据包的方式,个人认为可以分为两种。

    其一,我们直接用alloc_skb申请一个skb结构体,然后根据实际的应用填充不同的成员,或者基于当前数据包的skb,调用skb_copy_expand()函数等新申请一个nskb,并且拷贝skb的内容。

    其二,也是个人比较常用的,就是直接在先前接收到的数据包skb上作修改,主要有源IP、目IP,如果是TCP/UDP协议的话,还有源端口目的端口号。总之,就是根据自己的需求去调整数据包的相关成员即可。

    通常,这两种方式最终可能都要涉及到重新计算各个部分的校验和,这也是必须的。

    二、如何发送构造的数据包

    承接上文,数据包已经构造完毕,下一步关键就是如何发送数据包了。个人这里总结的有两种方法。

    方法一,就是让数据包接着按照Netfilter的流程进行传输。因为数据包的一些内容已经被更改,尤其是当源IP和目的IP被更改,主要是交换的情况下,是需要确保有路由可查的。

    NF框架中查路由的位置一是在PREROUTING之后,而是在LOCALOUT之后。又由于这里是需要将数据包从本地发送出去。因此,可以考虑让修改后的数据包从LOCALOUT点发出。

    内核代码中有这种方式的典型体现。本文涉及的相关内核代码的版本都是2.6.18.3。源文件为ipt_REJECT.c,函数send_reset用于往当前接收到数据包的源IP上发送RST包,整个函数涉及了数据包的构造和发送,这里一起做个简单分析。

    /* Send RST reply */

    static void send_reset(struct sk_buff *oldskb, int hook)

    {

    struct sk_buff *nskb;

    struct iphdr *iph = oldskb->nh.iph;

    struct tcphdr _otcph, *oth, *tcph;

    struct rtable *rt;

    u_int16_t tmp_port;

    u_int32_t tmp_addr;

    int needs_ack;

    int hh_len;

    /* 判断是否是分片包*/

    if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))

    return;

    /*得到TCP头部指针*/

    oth = skb_header_pointer(oldskb, oldskb->nh.iph->ihl * 4,

    sizeof(_otcph), &_otcph);

    if (oth == NULL)

    return;

    /* 当期收到的包就是RST包,就不用再发送RST包了*/

    if (oth->rst)

    return;

    /*检查数据包的校验和是否正确*/

    if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP))

    return;

    /*这一步比较关键,做的就是更新路由的工作。该函数的主要工作就是将当前数据包的源IP当做路由的目的IP,同时考虑数据包的目的IP,得到去往该源IP的路由*/

    if ((rt = route_reverse(oldskb, oth, hook)) == NULL)

    return;

    hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);

    /* 拷贝当前的oldskb,包括skb结构体和数据部分。这就是我们上面提到的构造数据包的第一种方式*/

    nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),

    GFP_ATOMIC);

    if (!nskb) {

    dst_release(&rt->u.dst);

    return;

    }

    /*因为是拷贝的oldskb,这里不需要再引用了,因此释放对该路由项的引用*/

    dst_release(nskb->dst);

    /*将新构造数据包引用的路由指向上面由route_reverse函数返回的新的路由项 */

    nskb->dst = &rt->u.dst;

    /* 清除nskb中拷贝过来的oldskb中链接跟踪相关的内容*/

    nf_reset(nskb);

    nskb->nfmark = 0;

    skb_init_secmark(nskb);

    /*以下就是构造数据包的实际数据部分。如果我们将这里不为nskb新申请缓冲区,而直接指向oldskb的缓冲区,就使我们上面提到的第二种构造数据包的方法。*/

    /*获取nskb的tcp header*/

    tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);

    /*交换源和目的IP */

    tmp_addr = nskb->nh.iph->saddr;

    nskb->nh.iph->saddr = nskb->nh.iph->daddr;

    nskb->nh.iph->daddr = tmp_addr;

    /*交换源和目的端口 */

    tmp_port = tcph->source;

    tcph->source = tcph->dest;

    tcph->dest = tmp_port;

    /*重置TCP头部的长度,并修改IP头部中记录的数据包的总长度。因为这里是发送RST报文,只需要有TCP的头部,不需要TCP的数据部分*/

    tcph->doff = sizeof(struct tcphdr)/4;

    skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));

    nskb->nh.iph->tot_len = htons(nskb->len);

    /*重新设置 seq, ack_seq,分两种情况(TCP/IP详解有描述)*/

    if (tcph->ack) { /*原始数据包中ACK标记位置位的情况*/

    needs_ack = 0;

    tcph->seq = oth->ack_seq; /*原始数据包的ack_seq作为nskb的seq*/

    tcph->ack_seq = 0;

    } else { /*原始数据包中ACK标记位没有置位的情况,初始连接SYN或者结束连接FIN等*/

    needs_ack = 1;

    /*这种情况应该是SYN或者FIN包,由于SYN和FIN包都占用1个字节的长度。因此ack_seq应该等于旧包的seq+1即可。这里之所以这样表示,可能是还存在其他情况的数据包。*/

    tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin

    + oldskb->len - oldskb->nh.iph->ihl*4

    - (oth->doff<<2));

    tcph->seq = 0;

    }

    /* RST标记位置1*/

    ((u_int8_t *)tcph)[13] = 0;

    tcph->rst = 1;

    tcph->ack = needs_ack;

    tcph->window = 0;

    tcph->urg_ptr = 0;

    /*重新计算TCP校验和*/

    tcph->check = 0;

    tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),

    nskb->nh.iph->saddr,

    nskb->nh.iph->daddr,

    csum_partial((char *)tcph,

    sizeof(struct tcphdr), 0));

    /* 修改IP包的TTL,并且设置禁止分片*/

    nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);

    /* Set DF, id = 0 */

    nskb->nh.iph->frag_off = htons(IP_DF);

    nskb->nh.iph->id = 0;

    /*重新计算IP数据包头部校验和*/

    nskb->nh.iph->check = 0;

    nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,

    nskb->nh.iph->ihl);

    /* "Never happens" */

    if (nskb->len > dst_mtu(nskb->dst))

    goto free_nskb;

    /*使nskb和oldskb的链接记录关联*/

    nf_ct_attach(nskb, oldskb);

    /*这里就是最终发送数据包的方式,具体方法就是让新数据包经过LOACLOUT的hook点,然后查路由,最后经由POSTROUTING点,将数据包发送出去。

    其实这里我还是有1个疑问:(1)为什么不可以直接查找路由,而必须先经过LOCALOUT点*/

    NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,

    dst_output);

    return;

    free_nskb:

    kfree_skb(nskb);

    }

    通过以上对send_reset函数的分析,应该明白了利用NF框架将构造数据包发送出去的方法。

    源码分析中提到的1个疑问,35楼给出了解释,这里引用过来:

    其实,这不是丢到了高层,而是和ip_queue_xmit()发送过程意义一样。

    对这包进行重新路由后,封装了头部,之后,放到了NF_IP_LOCAL_IN之前而已。

    其实,这里面只要修改了中途修改了ip地址,肯定是需要手动重新路由的。

    这就涉及到一些比较复杂的route cache的查找,如果没有就去查找route tables;之后,进行路由结构和neighbour结构的关联,就涉及到邻居子系统的相关操作;接着就涉及到arp cache的查找,如果没有,进行一些操作,arp的过程等等,才找到了相关的ip对应的mac信息。

    息。

    方法二,就是直接调用dev_queue_xmit函数,将构造完毕的数据包直接发送到网卡驱动。从NF框架来看,该函数的调用是在POSTROUTING点之后了,也可以理解为直接通过调用二层的发送函数,将三层构造的数据包发送出去。该函数实际上会调用skb->dev->hard_start_xmit,即对应网卡的驱动函数,将数据包直接发送的出去。

    很显然,这个工作在二层的函数,发送数据包(数据包在二层的时候准确叫法应该是帧,我们这里是在三层直接调用的,权且还称作数据包)的方式是不需要再查路由了。

    但是,二层发送的时候是需要根据目的MAC来进行的。在第一种方法构造的数据包中,仅仅交换了IP地址,而没有对MAC做任何修改。这样直接调用dev_queue_xmit是会产生问题的,并且该函数发送的内容应该是从二层头部开始,到数据包的结束。因此,如果三层构造的数据包,想调用该函数直接发送数据包的话,则需要修改数据包的源和目的MAC,并将skb->data指针指向MAC头部,以及skb->len的值也要加上头部的长度方法。以下是可参考的示例代码:

    unsigned char mac_temp[ETH_ALEN] = {0};

    struct ethhdr *mach = NULL;

    ……

    /*code…… 构造数据包的IP即上层协议及数据*/

    ……

    /*交换源和目的MAC*/

    mach = (struct ethhdr *)skb->mac.raw;

    memcpy(mac_temp, (unsigned char *)mach->h_dest, ETH_ALEN);

    memcpy(mach->h_dest, (unsigned char *)mach->h_source, ETH_ALEN);

    memcpy(mach->h_source, mac_temp, ETH_ALEN);

    /*修改skb->data指针,使其指向MAC头部,并且增加skb->len*/

    skb_push(skb , ETH_HLEN);

    /*直接调用该函数,将数据包从网卡上发送出去*/

    ret = dev_queue_xmit(skb);

    这里还要顺便说一下构造的数据包发送完毕之后,对于hook函数的返回值问题。    (1)第一种发送数据包的实现,对于send_reset函数的实现中,由于单独申请了nskb的内存,并构造的新的数据包。新数据包接着走NF的流程了。而对于原始的skb,就通过模块的返回值return NF_DROP做出了处理。    (2)第二种发送数据包的实现,若是基于已有数据包的基础上重新构造的数据包,那么实际上原始数据包的内容已经不复存在,而且调用完毕dev_queue_xmit已将同一块缓冲区,只是填充了新数据的数据包发送出去,因此,这里已经没有原始数据包的存在了,需要返回NF_STOLEN,告诉协议栈不用关心原始的包即可。否则,若是新数据包是单独申请的内存,那么对于原数据包还应该是返回NF_DROP. 三、总结         以上就是个人分享和总结和内核中构造的数据包发送出去的两种方式。实际中常用的就是构造完数据包之后,调用dev_queue_xmit函数发送报文,也测试过调用send_reset发送RST方式。但并未采用send_reset中通过调用NF_HOOK发送过其他数据包。如果诸位朋友有相关的实践经验,欢迎分享。         本文在分析send_reset代码的过程中,参考了百度中搜到的muddoghole的文章,因为只能从百度快照看到这篇文章,并且链接过长,这里就不列出连接,对于原文的作者表示感谢。         由于对内核中的一些地方理解不够深入,因此文章中肯定存在很多问题。欢迎各位朋友指正,多多交流。         本文原文链接:http://blog.chinaunix.net/u/33048/showart_2043789.html

    展开全文
  • 我正在尝试将以下数据发送到将使用C的服务器:static int user_id; // 4 Bytesstatic byte state; // 1 Bytestatic String cipher_data; // 128 Bytesstatic String hash; // 128 Bytesstatic final int PACKET_SIZE...

    我正在尝试将以下数据发送到将使用C的服务器:

    static int user_id; // 4 Bytes

    static byte state; // 1 Byte

    static String cipher_data; // 128 Bytes

    static String hash; // 128 Bytes

    static final int PACKET_SIZE = 261;

    public static byte [] packet = new byte [PACKET_SIZE];

    我正在尝试创建一个字节数组,其中将包括所有这些字节数组:

    ByteArrayOutputStream baos = new ByteArrayOutputStream(PACKET_SIZE);

    DataOutputStream dos = new DataOutputStream(baos);

    dos.write(state);

    dos.writeInt(user_id);

    for (int i = 0; i < cipher_data.length(); i++) {

    dos.write((byte) cipher_data.charAt(i));

    }

    for (int i = 0; i < cipher_data.length(); i++) {

    dos.write((byte) hash.charAt(i));

    }

    packet = baos.toByteArray();

    现在,我有了包含所有数据的字节数组,但是我不确定我在做什么,是否正确,以及是否可以从服务器端读取所有这些数据.如果您能给我一些建议,我将不胜感激,

    谢谢,

    展开全文
  • 那就考虑到有可能是网卡自身有硬件故障,考虑到有硬件故障的网卡如果仍然接入到网络中的话,可能会向网络中不停地发送广播信息,会不会是大量的垃圾广播信息阻碍了网络的正常传输。 如果是这样那么就开始对网卡设备...
  • 如果我们假定MTU为1500来发送数据的,而途经的某个网络的MTU值小于1500字节,那么系统将会使用一系列的机制来调整MTU值,使数据报能够顺利到达目的地,这样就会做许多不必要的操作。 3.结语 鉴于Internet上的标准MTU值...
  • 例如,我在Windows上发送100000个UDP数据包.对于每个数据包,我需要调用一次WSASendTo(),因此可能会引入大量的系统调用开销.有没有办法进行批量发送并减少这种开销?谷歌搜索一段时间后,我找不到适合Windows的解决方案...
  • 计算机网络课程设计——机械工业出版社第5章:发送ARP数据包课程设计目的:ARP协议用于完成IP地址与MAC 地址之间的转换。熟悉ARP协议对于IP数据包的传送过程具有重要意义。本课程设计的主要目的是通过封装与发送ARP...
  • 我试图使用名为“lua socket”的lua库,以便在两台计算机之间发送udp数据包 .我已经从here复制了一些非常通用的服务器和客户端脚本,以查看数据包是否实际到达 .我的桌面配置为在LAN中具有静态专用IP地址,如果我...
  • 继上一篇介绍了数据包的接收过程后,本文将介绍在Linux系统中,数据包是如何一步一步从应用程序到网卡并最终发送出去的。如果英文没有问题,强烈建议阅读后面参考里的文章,里面介绍的更详细。本文只讨论以太网的...
  • 我看到当我们制作ICMP echo-r​​equest数据包并使用sr()发送/接收时,我们看不到它被发送出接口,因此没有来自目的地的响应.但是如果我们使用srp()函数,我们会看到相同的数据包响应.什么时候应该使用sr()和srp()?在...
  • 计算机网络课程设计——机械工业出版社第5章:发送ARP数据包课程设计目的:ARP协议用于完成IP地址与MAC 地址之间的转换。熟悉ARP协议对于IP数据包的传送过程具有重要意义。本课程设计的主要目的是通过封装与发送ARP...
  • 我不确定你使用的是什么方法 .但在C#中有2个可用作服务器的常用类:TcpClient&Socket在 TcpClient...//Start ServerInt32 port = 13000;IPAddress localAddr = IPAddress.Parse("127.0.0.1");...
  • 更新(回答你的评论): 首先,您应该知道从TCP套接字接收可能不会提供整个数据包.您需要实现循环(如Nemo所建议)来读取整个数据包.由于您更喜欢第二个选项,因此您需要两个循环.第一个循环是读取数据包标头以提取有效...
  • 我正在尝试从多播(239.255.255.251:5353)接收许多数据包,我想为特定设备发送数据包组播(239.255.255.251:5353) .我从boost引用了这个例子...
  • 恢复:我尝试使用smack在Android应用中发送和接收自定义IQ数据包。情境:我必须向服务器发送一个iq数据包(IQP),告诉它我需要信息。然后服务器在收到此IQP时,发送另一个包含带有该信息的xml的IQP。客户端:服务器{...
  • 为了在FPGA上实现以太网接收功能,我正在用C#编写一个程序来发送数据包,然后从FPGA中读取答案(如果我的接收功能正在工作,FPGA应该发送相同的数据包) . 它是FPGA与计算机之间的点对点连接,无交换机或路由器 ....
  • 关于51单片机串口1发送完整的数据包 在参考这样的协议的条件下我们想发送一套完整的数据包该如何发送呢?可以设计这样的程序。 1. 串行口1接收特定包头数据包函数。 参数: Uart_Rec_Data:串口接收到的数据 ; USER...
  • 对于以太网环境下UDP传输中的数据包长度问题首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层。其中以太网(Ethernet)的数据帧在链路层IP包在网络层TCP或UDP包在传输层TCP或UDP中的数据(Data)在应用...
  • shell给tcp或udp服务发送16进制报文指令 通过/dev/tcp、/dev/udp (https://blog.csdn.net/u010039418/article/details/86251470) 通过/dev/tcp、/dev/udp可以直接在shell脚本中发起tcp、udp连接...
  • sokit 是一款开源免费的 TCP / UDP 测试(调试)工具, 可以用来接收,发送或转发TCP/UDP数据包。本程序可以工作在三种模式: 服务器模式,用来监听本地端口,接收外部数据包,并且可以回复自定义数据; 客户端模式,...
  • 继上一篇介绍了数据包的接收过程后,本文将介绍在Linux系统中,数据包是如何一步一步从应用程序到网卡并最终发送出去的。 如果英文没有问题,强烈建议阅读后面参考里的文章,里面介绍的更详细。 本文只讨论以太网...
  • Windows : ping -SLinux : ping -I -I interfaceinterface is either an address, or an interface name. If interface is an address, it sets source address to specified interface address....
  • 数据包发送与接收

    千次阅读 2021-12-09 18:37:52
    数据包发送与接收的过程
  • 我一直在尝试从我的自定义Cocoa应用程序(写在Objective-C当然)发送数据包到我的世界服务器。尽管如此,但我有点困惑。我是用Java做的。这很容易。尽管这样做是客观的,但事实证明它更具挑战性。发送数据包到我的世界...
  • 现在,如果错过了一个警报,你的数据包发送将会变慢(你会错过一个插槽),但是你会在stderr上收到有关它的消息. 上面的一个重要问题是它取决于您的系统计时器分辨率.在Linux上,这在很程度上取决于内核配置CONFIG_HIGH...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 337,685
精华内容 135,074
关键字:

发送大数据包