- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有包含数百万个数据包的捕获数据包的 tcpdumps (.pcap) 文件。我需要将这些网络数据包分组到 TCP 流中。
例子:让我们考虑以下数据包no => source_ip, destination_ip,source_port,destination_port
1 => ip1, ip2, s1, s2
2 => ip1, ip3, s3, s4
3 => ip2,ip1,s2,s1
4 => ip3,ip1,s4,s3
现在在上面的四个数据包的例子中,数据包 1,3 和 2,4 是同一个流的数据包。即我需要将以下数据包解析为 [[1,3],[2,4]]。
我的方法:
由于 (ip1, ip2, s1, s2) 和 (ip2, ip1, s2, s1) 表示相同的流,所以我决定对它们进行哈希处理并将其命名为 forward_hash 和 reverse hash,因为它们表示流过相同流的数据包在相反的方向。
我使用索引数组在替换和排序期间跟踪数据包。最终排序后,提取相同哈希值的开始和结束,并将其用于索引数组以获取表示该流的数据包索引
keys is the forward_hash of each packets,
count is number of packets,
packet_ids is the id of each packet corresponding to each of the hash
thrust::device_vector<unsigned long long> d_keys(keys,(keys+count));
thrust::device_vector<unsigned long long> d_ids(packet_ids,(packet_ids+count));
// now sort the ids according to the keys
thrust::sort_by_key(d_keys.begin(), d_keys.end(), d_ids.begin());
// after sorting, now we need to find the index of each hash
thrust::device_vector<unsigned long long> u_keys(count);
thrust::device_vector<unsigned long long> output(count);
thrust::pair<thrust::device_vector<unsigned long long>::iterator, thrust::device_vector<unsigned long long>::iterator> new_end;
new_end = thrust::reduce_by_key(d_keys.begin(), d_keys.end(),thrust::make_constant_iterator(1),u_keys.begin(),output.begin());
// now we need to find starting index to each hash
....
我已经尝试为唯一的正向和反向哈希实现哈希表查找,但是在排序之前用正向哈希替换每个反向哈希......但是性能很慢。我有帮助吗?
谢谢
最佳答案
我提出另一种方法,首先对每个数据包内进行排序,然后对数据包进行排序。
示例代码执行以下步骤:
为了识别同一TCP流的数据包,我们需要对数据包进行排序。在此之前,我们需要确保在中每个发送的数据包源和目标都已排序。示例:20:1 -> 10:4
变为 10:4 -> 20:1
现在我们可以对数据包进行排序,以便将同一流的数据包分组。此代码假定输入数据包按时间排序。我们应用稳定排序,以便在每个流中保持排序。
我们需要找出每个 TCP 流的起始位置。此步骤的结果是指向已排序数据包列表中 TCP 流开头的索引。
根据您需要结果的方式,我们可以生成有关流的其他信息,例如每个流的数据包数。
可能的改进:
如果您知道 IP 地址仅在某个有限范围内,则可能仅使用 16 位来表示它们。然后,您可以将发送方地址、发送方端口、接收方地址、接收方端口压缩为一个 64 位整数,这将提高排序性能。
编译运行
nvcc -std=c++11 sort_packets.cu -o sort_packets && ./sort_packets
输出
input data
d_src_addr: 20 10 20 20 30 30 10 20 30 20
d_src_port: 1 2 3 1 2 2 6 1 1 1
d_dst_addr: 10 20 30 10 20 20 30 10 10 10
d_dst_port: 4 2 3 4 5 5 1 4 6 4
packets after sort_within_packet
d_src_addr: 10 10 20 10 20 20 10 10 10 10
d_src_port: 4 2 3 4 5 5 6 4 6 4
d_dst_addr: 20 20 30 20 30 30 30 20 30 20
d_dst_port: 1 2 3 1 2 2 1 1 1 1
after stable_sort
d_orig_ind: 1 0 3 7 9 6 8 2 4 5
packets after stable_sort
d_src_addr: 10 10 10 10 10 10 10 20 20 20
d_src_port: 2 4 4 4 4 6 6 3 5 5
d_dst_addr: 20 20 20 20 20 30 30 30 30 30
d_dst_port: 2 1 1 1 1 1 1 3 2 2
after copy_if
d_start_indices: 0 1 5 7 8
d_stream_lengths: 1 4 2 1 2
group of streams referencing the original indices
[1] [0,3,7,9] [6,8] [2] [4,5]
sort_packets.cu
#include <stdint.h>
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/iterator/transform_iterator.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/sort.h>
#include <thrust/sequence.h>
#include <thrust/copy.h>
#include <thrust/functional.h>
#include <thrust/adjacent_difference.h>
#include <thrust/scatter.h>
#define PRINTER(name) print(#name, (name))
template <template <typename...> class V, typename T, typename ...Args>
void print(const char* name, const V<T,Args...> & v)
{
std::cout << name << ":\t";
thrust::copy(v.begin(), v.end(), std::ostream_iterator<T>(std::cout, "\t"));
std::cout << std::endl;
}
typedef thrust::tuple<uint32_t, uint16_t, uint32_t, uint16_t> Packet;
struct sort_within_packet : public thrust::unary_function<Packet, Packet>
{
__host__ __device__
Packet operator()(Packet p) const
{
if (thrust::get<0>(p) > thrust::get<2>(p))
{
Packet copy(p);
thrust::get<0>(p) = thrust::get<2>(copy);
thrust::get<1>(p) = thrust::get<3>(copy);
thrust::get<2>(p) = thrust::get<0>(copy);
thrust::get<3>(p) = thrust::get<1>(copy);
}
return p;
}
};
struct find_start_indices : public thrust::unary_function<thrust::tuple<Packet, Packet>, bool>
{
__host__ __device__
bool operator()(thrust::tuple<Packet, Packet> p)
{
return (thrust::get<0>(p) != thrust::get<1>(p));
}
};
template<typename... Iterators>
__host__ __device__
thrust::zip_iterator<thrust::tuple<Iterators...>> zip(Iterators... its)
{
return thrust::make_zip_iterator(thrust::make_tuple(its...));
}
int main()
{
// in this example we just have 10 packets
const int N = 10;
// demo data
// this example uses very simple "IP addresses"
uint32_t srcAddrArray[N] = {20, 10, 20, 20, 30, 30, 10, 20, 30, 20};
uint16_t srcPortArray[N] = {1 , 2 , 3 , 1 , 2 , 2 , 6 , 1 , 1 , 1 };
uint32_t dstAddrArray[N] = {10, 20, 30, 10, 20, 20, 30, 10, 10, 10};
uint16_t dstPortArray[N] = {4 , 2 , 3 , 4 , 5 , 5 , 1 , 4 , 6 , 4 };
// upload data to GPU
thrust::device_vector<uint32_t> d_src_addr(srcAddrArray, srcAddrArray+N);
thrust::device_vector<uint16_t> d_src_port(srcPortArray, srcPortArray+N);
thrust::device_vector<uint32_t> d_dst_addr(dstAddrArray, dstAddrArray+N);
thrust::device_vector<uint16_t> d_dst_port(dstPortArray, dstPortArray+N);
thrust::device_vector<uint32_t> d_orig_ind(N);
thrust::sequence(d_orig_ind.begin(), d_orig_ind.end());
std::cout << "input data" << std::endl;
PRINTER(d_src_addr); PRINTER(d_src_port); PRINTER(d_dst_addr); PRINTER(d_dst_port); std::cout << std::endl;
// 1. sort within packet
auto zip_begin = zip(d_src_addr.begin(), d_src_port.begin(), d_dst_addr.begin(), d_dst_port.begin());
auto zip_end = zip(d_src_addr.end(), d_src_port.end(), d_dst_addr.end(), d_dst_port.end());
thrust::transform(zip_begin, zip_end, zip_begin, sort_within_packet());
std::cout << "packets after sort_within_packet" << std::endl;
PRINTER(d_src_addr); PRINTER(d_src_port); PRINTER(d_dst_addr); PRINTER(d_dst_port); std::cout << std::endl;
// 2. sort packets
thrust::stable_sort(zip(d_src_addr.begin(), d_src_port.begin(), d_dst_addr.begin(), d_dst_port.begin(), d_orig_ind.begin()),
zip(d_src_addr.end(), d_src_port.end(), d_dst_addr.end(), d_dst_port.end(), d_orig_ind.end()));
std::cout << "after stable_sort" << std::endl;
PRINTER(d_orig_ind); std::cout << std::endl;
std::cout << "packets after stable_sort" << std::endl;
PRINTER(d_src_addr); PRINTER(d_src_port); PRINTER(d_dst_addr); PRINTER(d_dst_port); std::cout << std::endl;
// 3. find stard indices of each stream
thrust::device_vector<uint32_t> d_start_indices(N);
using namespace thrust::placeholders;
thrust::device_vector<uint32_t>::iterator copyEnd = thrust::copy_if(thrust::make_counting_iterator(1), thrust::make_counting_iterator(N),
thrust::make_transform_iterator(
zip(
zip(d_src_addr.begin(), d_src_port.begin(), d_dst_addr.begin(), d_dst_port.begin()),
zip(d_src_addr.begin()+1, d_src_port.begin()+1, d_dst_addr.begin()+1, d_dst_port.begin()+1)
),
find_start_indices()
),
d_start_indices.begin()+1, _1);
uint32_t streamCount = copyEnd-d_start_indices.begin();
d_start_indices.resize(streamCount);
std::cout << "after copy_if" << std::endl;
PRINTER(d_start_indices);
// 4. generate some additional information about the result and print result formatted
thrust::device_vector<uint32_t> d_stream_lengths(streamCount+1);
thrust::adjacent_difference(d_start_indices.begin(), d_start_indices.end(), d_stream_lengths.begin());
d_stream_lengths.erase(d_stream_lengths.begin());
d_stream_lengths.back() = N-d_start_indices.back();
PRINTER(d_stream_lengths);
thrust::host_vector<uint32_t> h_start_indices = d_start_indices;
thrust::host_vector<uint32_t> h_orig_ind = d_orig_ind;
auto index = h_start_indices.begin();
index++;
std::cout << std::endl << "group of streams referencing the original indices"<< std::endl << "[" << h_orig_ind[0];
for(int i=1; i<N;++i)
{
if (i == *index)
{
index++;
std::cout << "]\t[";
}
else
{
std::cout << ",";
}
std::cout << h_orig_ind[i];
}
std::cout << "]" << std::endl;
return 0;
}
关于c++ - 基于 cuda 推力的方法对 TCP 流中的数据包进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31305929/
使用 Python 的 rtmplib 绑定(bind)并遇到一些问题。 首先, 我有这样的东西: import librtmp conn = librtmp.RTMP(...) conn.con
基本上,我是在查看 Motorstorm 排行榜时在 PS3 上窃听数据包。排行榜以 XML 格式发送到我的 ps3,但只有在我获得授权后。那么有人可以告诉我这三个数据包之间发生了什么,以及我如何在浏
我正在努力了解 TCP,但解析大量 RFC 并没有帮助。我相信我了解连接和关闭握手,但我似乎无法找到任何总结实际数据流的内容。 在连接和关闭握手之间 TCP 数据包看起来像什么? (特别是标题) 最佳
我正在尝试通过 RCON 端口与我的 Minecraft 服务器通信。 虽然我不知道如何使用套接字和流的东西。四处寻找,我发现他们都有一些共同点。套接字、输入流和输出流。 我在我的代码中试过了,但返回
我正在 UDP 之上设计一个简单的协议(protocol),现在我意识到其他人可以将数据包发送到我正在监听的端口。这样的数据包对于我的应用程序来说显然是不正确的(我现在不担心安全问题) 是否有过滤这些
我目前有一个具有可自定义滴答率的游戏服务器,但在本示例中,我们建议服务器每秒仅滴答一次或 1hz。我想知道如果客户端发送速率比服务器快,因为我当前的设置似乎不起作用,那么处理传入数据包的最佳方法是什么
我无法理解网络字节顺序以及通过 UDP 发送和接收数据的顺序。我正在使用 C#。 我有一个结构保持: message.start_id = 0x7777CCCC; message.me
我正在为 USB 设备编写代码。假设 USB 主机开始控制读取传输以从设备读取一些数据,并且请求的数据量(设置数据包中的 wLength)是端点 0 最大数据包大小的倍数。那么在主机接收到所有数据后(
我有一台 Windows PC、Marvell 交换机、Netgear 交换机和一台 Ubuntu 机器连接在一起(通过 Netgear 交换机)。 我最近从 Windows PC 向 Marvell
在查看数据包字节码时,您将如何识别 dns 数据包。 IP header 的协议(protocol)字段会告诉后面有一个 UDP 帧,但是在 UDP 帧内没有协议(protocol)字段来指定接下来会
我有一个通过 udf 的 802.11 (wifi) 上各种类型的流量的 pcap。由于 MTU,udp(或更准确地说是 IP)对 wifi 数据包进行分段。我目前正在使用 SharpPcap 读取并
我正在开发的 Core Audio 应用程序上有此崩溃日志。我目前正在调试它,所以我的问题不是关于崩溃本身,而是关于 的含义“k”包 . 这是什么意思 ? 我已阅读 this , 和 this (关于
我在一台 VM Ubuntu 16.04 机器上的 100 个多播组上生成 UDP 数据包,并在另一台 VM Ubuntu 16.04 机器上订阅这些组。两者都在由 Hyper-V 管理器运行的 HP
这个问题在这里已经有了答案: How can I fix 'android.os.NetworkOnMainThreadException'? (66 个回答) 6年前关闭。 我正在尝试创建一个简单的
我正在寻找使用 Java 来欺骗 UDP 数据包。是否有任何好的 Java 库可以让您创建自己的 RAW SOCKETS? 最佳答案 我会使用包装 libpcap 的 Java API . libpc
我在基于 Tyrus 的客户端和 tomcat Web 服务器之间使用没有压缩的 websocket。我在 tomcat 端看到消息传入和传出我的套接字,但如果我设置一个wireshark来观察它们传
我的应用程序在模拟器中运行时无法接收 UDP 数据包。 UDP 数据包由“localhost”上的以下 java 程序通过端口 49999 发送。 DatagramSocket clien
我正在开发一个 Google Glass 应用程序,它需要在工作线程中监听 UDP 数据包(与发送 UDP 数据包的现有系统集成)。我之前发布了一个问题(请参阅 here )并收到了一个答案,其中提供
我正在从客户端向服务器发送两个数据包。我遇到的问题是,在服务器上读取的数据使两个字符串对于发送的最长字符串具有相同的长度。例如: 如果字符串 1 为:1234 字符串 2 为:abcdefghi 服务
我知道这是不好的做法,但是可以执行以下操作吗? Send packet1 to UDP port 1 port 1 receives packet1 and sends it to port 2 po
我是一名优秀的程序员,十分优秀!