将字节传递给另一个调用 ::recv() 的应用程序。

huangapple go评论65阅读模式
英文:

Deliver bytes to another application which calls ::recv()

问题

  1. 有没有可能在不更改调用 ::recv() 代码的情况下将处理后的数据包字节传递给第二个应用程序?
  2. 我还想将 ::send() 的调用“重定向”到第一个应用程序。我认为可以使用动态库和 LD_PRELOAD 来实现这一点,但是否可以通过静态技术来实现?
英文:

I have a userspace C++ application (could be a library) processing packets.

I have a second application (written in C) which obtains bytes via calling ::recv().

  1. Is it possible to "deliver" the processed packet bytes to the second application, without changing the code calling ::recv()?
  2. I'd also like to "divert" calls from ::send() to the first application. I think I can do this using a dynamic library and LD_PRELOAD, but is it possible to do via a static technique?

答案1

得分: 1

根据我的理解,您希望能够以一种特殊模式运行任何未经修改的程序,其中它的所有套接字都连接到模拟网络的您自己的程序,而不是实际网络。这是为了帮助开发一些自定义网络代码。

也许最简单的方法是使用LD_PRELOAD - 这是经常用于覆盖标准库函数的机制。

您可以创建一个共享库,其中包含像recvsend等函数名称,以及您需要覆盖的其他任何函数,然后在运行第二个程序时设置环境变量LD_PRELOAD=my_socket_library.so(将其更改为实际的文件名)。加载器将会将recvsend的调用链接到您的函数,而不是libc中的函数,因为LD_PRELOAD库具有优先级。如果您希望调用原始函数,可以使用dlsymRTLD_NEXT来获取指向它们的指针(超出范围,请搜索更多信息)。

另外,您可能更喜欢将它变成一个真正的套接字,连接到您的网络程序。您的网络程序将侦听某个端口(使用内核网络系统),并且您的共享库将覆盖connect函数,使其连接到网络程序侦听的端口,然后告诉网络程序地址。除非程序使用getpeername来查看它连接到的地址(大多数程序不这样做,因为它们已经知道它们连接到哪个地址),否则它不会察觉到任何差异,但由于它是一个真正的套接字,它将适用于程序执行的任何套接字操作。

英文:

As I understand, you want to be able to run any unmodified program in a special mode where all its sockets get connected to your own program which emulates the network, instead of the actual network. This is to help develop some custom networking code.

Perhaps the simplest way to do this is with LD_PRELOAD - a mechanism that is often used for overriding standard library functions.

You can make a shared library with function names like recv and send, and anything else you need to override, and then set the environment variable LD_PRELOAD=my_socket_library.so (change it to the actual filename) when running the second program. The loader will link recv and send calls to your functions instead of the ones in libc, because LD_PRELOAD libraries take priority. If you want to call the original functions you can use dlsym iwth RTLD_NEXT to get pointers to them (out of scope; Google for more information).

Alternatively, you might prefer to make it a real socket, connected to your networking program. Your networking program would listen on some port (using the kernel networking system) and your shared library would override the connect function so it connects to the port where the networking program was listening, then tells the networking program the address. Unless the program uses getpeername to see the address it's connected to (and most programs don't, because they already know which address they connected to) it won't know the difference, but since it's a real socket it would work no matter what socket stuff the the program did.

huangapple
  • 本文由 发表于 2023年2月24日 04:04:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75549799.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定