libpcap 中的数据包向量

发布于 2024-12-13 08:41:26 字数 628 浏览 1 评论 0原文

我正在使用 c / c++ 中的 libpcap,并且在向量中插入指针时遇到问题。 这是我的代码:

    typedef vector <u_char *>vPack;
    ...
    vPack vect;
    ...
    if (pcap_dispatch (p, 0, &mycallback, (u_char *) &vect) < 0){
         cout << "Error" << endl;
          pcap_perror (p, prestr);
    }
    ....
    void mycallback (u_char * args, const struct pcap_pkthdr *pkthdr, const u_char * packet){
          u_char *pk;
          pk = (u_char *)packet;
          vPack *vec = (vPack *) args;
          vec[0].push_back(pk);
        }

问题是元素被插入到相同的内存位置,并且向量始终包含相同的元素。 有什么建议吗?

PD:对不起我的英语。

I'm working with libpcap in c / c + + and I have a problem when inserting pointers in a vector.
This is my code:

    typedef vector <u_char *>vPack;
    ...
    vPack vect;
    ...
    if (pcap_dispatch (p, 0, &mycallback, (u_char *) &vect) < 0){
         cout << "Error" << endl;
          pcap_perror (p, prestr);
    }
    ....
    void mycallback (u_char * args, const struct pcap_pkthdr *pkthdr, const u_char * packet){
          u_char *pk;
          pk = (u_char *)packet;
          vPack *vec = (vPack *) args;
          vec[0].push_back(pk);
        }

The problem is that the elements are inserted in the same memory location, and the vector always contains the same element.
Any suggestions?

PD: sorry for my english.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

百变从容 2024-12-20 08:41:26

mycallback中,参数packet是一个const u_char - 缓冲区。该指针指向 libpcap 内部数据缓冲区,该缓冲区可重复用于与您的过滤器匹配的每个数据包(并且调用您的回调)。您必须创建自己的缓冲区并将数据包数据复制到其中。

例如:

u_char *b = malloc(pkthdr->caplen);
memcpy(b, pk, pkthdr->caplen);
vec[0].push_back(b);

In mycallback the argument packet is a const u_char - buffer. This pointer points to an libpcap-internal data buffer which is reused for every packet which has matched your filter (and your callback is called). You have to create your own buffer and copy the packet-data into it.

For example:

u_char *b = malloc(pkthdr->caplen);
memcpy(b, pk, pkthdr->caplen);
vec[0].push_back(b);
不顾 2024-12-20 08:41:26

您必须将数据复制到新分配的内存中:

void mycallback (u_char * args, const struct pcap_pkthdr *pkthdr, const u_char * packet)
{
    u_char *pk = new u_char [pkthdr->caplen];
    memcpy(pk, packet, pkthdr->caplen);
    vPack *vec = (vPack *) args;
    vec->push_back(pk);
}

但是,需要考虑一些重要问题:

  • 销毁向量时,您必须迭代每个元素并显式删除它,以恢复记忆。
  • 您不知道每个数据包在向量内的时间。您确实需要一个类来存储数据及其长度,然后存储这些对象的向量

You have to copy the data to a freshly allocated piece of memory:

void mycallback (u_char * args, const struct pcap_pkthdr *pkthdr, const u_char * packet)
{
    u_char *pk = new u_char [pkthdr->caplen];
    memcpy(pk, packet, pkthdr->caplen);
    vPack *vec = (vPack *) args;
    vec->push_back(pk);
}

However there are important issues to consider:

  • When destroying your vector you must iterate through each element and explicitly delete it, in order to recover memory.
  • You don't know long each packet is within the vector. You really need a class that stores both the data and its length and then store a vector of these objects instead.
小糖芽 2024-12-20 08:41:26

延长卡雷克的尝试!

struct packet_handler
{
  typedef std::vector<u_char> PacketType;
  typedef std::vector <PacketType> PacketBuffer;

  static void handler(u_char *user, const pcap_pkthdr *h, const u_char *bytes)
  {
    packet_handler* ph = reinterpret_cast<packet_handler*>(user);
    ph->handle(PacketType(bytes, bytes + h->caplen));
  }

  void handle(PacketType const& packet)
  {
    _packetBuffer.push_back(packet);
  }

  PacketBuffer _packetBuffer;
};

int main()
{
  packet_handler ph;
  // pass in the handler class as user data
  int result = pcap_dispatch(p, 0, packet_handler::handler, reinterpret_cast<uchar*>(&ph));
}

extending Karrek's attempt!

struct packet_handler
{
  typedef std::vector<u_char> PacketType;
  typedef std::vector <PacketType> PacketBuffer;

  static void handler(u_char *user, const pcap_pkthdr *h, const u_char *bytes)
  {
    packet_handler* ph = reinterpret_cast<packet_handler*>(user);
    ph->handle(PacketType(bytes, bytes + h->caplen));
  }

  void handle(PacketType const& packet)
  {
    _packetBuffer.push_back(packet);
  }

  PacketBuffer _packetBuffer;
};

int main()
{
  packet_handler ph;
  // pass in the handler class as user data
  int result = pcap_dispatch(p, 0, packet_handler::handler, reinterpret_cast<uchar*>(&ph));
}
剧终人散尽 2024-12-20 08:41:26

真是一团糟!让我们使用 文档 做出一个 C++ 答案:

typedef std::vector <u_char*> VPack;

void handler(u_char *user, const pcap_pkthdr *h, const u_char *bytes)
{
  VPack & v = *reinterpret_cast<VPack*>(user);
  v.insert(v.end(), bytes, bytes + h->caplen);
}

int main()
{
  VPack v;
  // ... populate p ...
  int result = pcap_dispatch(p, 0, handler, reinterpret_cast<uchar*>(&v));
}

这里唯一值得注意的一点是我们通过 user 参数传递一个指向 v 的指针,因此我们必须在两端进行一些类型不安全的转换。不过,这正是使用 C 回调函数的标志。

What a mess! Let's make a C++ answer, using the documentation:

typedef std::vector <u_char*> VPack;

void handler(u_char *user, const pcap_pkthdr *h, const u_char *bytes)
{
  VPack & v = *reinterpret_cast<VPack*>(user);
  v.insert(v.end(), bytes, bytes + h->caplen);
}

int main()
{
  VPack v;
  // ... populate p ...
  int result = pcap_dispatch(p, 0, handler, reinterpret_cast<uchar*>(&v));
}

The only noteworth point here is that we pass a pointer to v through the user argument, so we have to do some type-unsafe casting on both ends. That's just the hallmark of using a C callback function, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文