【发布时间】:2017-09-19 02:31:19
【问题描述】:
当前的 GNURadio UDP Sink/Source 块使用 UDP 将数据包发送进/出 NIC。它使用 boost asio 进行发送/接收。我需要修改这些 UDP 接收器/源块以处理带有 IP 的 UDP,以便现有功能通过 1GB 网卡以及添加提升原始套接字/协议,以便我们可以通过 10G 网卡发送没有 IP 的第 2 层数据包没有 IP 地址(接收器是具有自定义错误检查/恢复等功能的 FPGA)。
仅使用 C,我有测试程序,我可以根据需要制作数据包并将其发送出去并在另一端接收。他们来自:
Create a layer 2 / ethernet socket with boost asio raw socket (in C++) http://qiita.com/kadopoly/items/acafa01945e5cfe39270
由于 GNURadio 使用 C++,我需要修改 boost 套接字/协议设置以适应 udp_sink_impl.cc 和 udp_sink_impl.h 文件,以便发送数据包。
Stack Overflow 链接似乎是最直接的(我不是经验丰富的编码人员),我能够将它添加到我的 GNURadio 块中并让它传输。它没有正确发送transmitbuffer2缓冲区(发送了一个数据包,但内容错误),但确实发送了Hello World! streambuf 缓冲区正确,所以我不知道。但是它不处理 0x00,所以我不能用它来测试正在发送的 MAC 地址。
这是我目前拥有的:
udp_sink_impl.h sn-p:
char tmpHeaderBuff[12]; // 32-bit sync word (0xFFFFFFFF), 32-bit sequence num and 32-bit data size
unsigned char custom_type[2] = {0x82,0x00};
unsigned char ethHeader[12] = {0x00,0x0c,0x29,0x05,0x0d,0x15,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
unsigned char mac_str[6];
unsigned char dstMAC[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
unsigned char srcMAC[6];
/* 1G management stuff */
boost::asio::io_service d_io_service;
boost::asio::ip::udp::endpoint d_endpoint;
boost::asio::ip::udp::socket *udpsocket;
/* 1G management stuff */
/* 10G raw socket stuff */
typedef boost::asio::generic::raw_protocol raw_protocol_t;
typedef boost::asio::generic::basic_endpoint<raw_protocol_t> raw_endpoint_t;
boost::asio::io_service d_io_service10;
raw_protocol_t::socket *d_socket10;
/* 10G raw socket stuff */
udp_sink_impl.cc sn-p:
getMACAddress(d_send_iface,srcMAC);
/* Begin 1G management connection */
std::string s__port = (boost::format("%d") % port).str();
std::string s__host = host.empty() ? std::string("localhost") : host;
boost::asio::ip::udp::resolver resolver(d_io_service);
boost::asio::ip::udp::resolver::query query(s__host, s__port,
boost::asio::ip::resolver_query_base::passive);
d_endpoint = *resolver.resolve(query);
udpsocket = new boost::asio::ip::udp::socket(d_io_service);
udpsocket->connect(d_endpoint);
/* End 1G management connection */
/* Begin 10G management connection */
sockaddr_ll sockaddr;
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sll_family = PF_PACKET;
sockaddr.sll_protocol = htons(ETH_P_ALL);
sockaddr.sll_ifindex = if_nametoindex(send_iface.c_str());
sockaddr.sll_hatype = 1;
raw_protocol_t::socket d_socket10(d_io_service10, raw_protocol_t(PF_PACKET, SOCK_RAW)); /* Needs root or cap_net_raw permissions */
d_socket10.bind(raw_endpoint_t(&sockaddr, sizeof(sockaddr)));
/* End 10G management connection */
/* This currently does not work for unknown reason. Transmitted packet does NOT match buffer contents expected. But the streambuf seems to work. */
std::vector<boost::asio::const_buffer> transmitbuffer2;
transmitbuffer2.clear();
transmitbuffer2.push_back(boost::asio::buffer((const void *)srcMAC, sizeof(srcMAC)));
transmitbuffer2.push_back(boost::asio::buffer((const void *)dstMAC, sizeof(dstMAC)));
transmitbuffer2.push_back(boost::asio::buffer((const void *)custom_type, sizeof(custom_type)));
d_socket10.send(boost::asio::buffer(transmitbuffer2));
/* for testing */
boost::asio::streambuf buffer;
std::ostream stream( &buffer );
unsigned char const deadbeef[] = { 0xde, 0xad, 0xbe, 0xef }; // can't handle 0x00
stream << "Hello, World!!!"
<< reinterpret_cast< char const * >( deadbeef );
d_socket10.send(buffer.data());
} // Close constructor
.
.
.
udp_sink_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
.
.
.
udpsocket->send_to(transmitbuffer,d_endpoint);
最终,在 udp_sink_impl::work 函数中我想替换现有的 UDP 调用:
udpsocket->send_to(transmitbuffer,d_endpoint);
类似:
d_socket10->send(transmitbuffer);
目前,当我这样做时,没有发送任何数据包,并且似乎崩溃或退出程序而不是连续发送数据,所以我认为这是某种崩溃。
有人可以向我解释如何在 C++ 中为 UDP Sink/Source 块实现简单 Stack Overflow 示例或日语标记化原始套接字示例的指针吗? Sink(发送)目前是我优先于 Source(接收)的优先级。
提前非常感谢。非常感谢任何帮助或建议。
【问题讨论】:
-
欢迎来到 Stack Overflow!请edit您的代码将其减少为您的问题的minimal reproducible example。您当前的代码包含许多与您的问题无关的内容 - 一个最小样本通常看起来类似于一个好的单元测试:只执行一项任务,并为可重复性指定输入值。
-
对不起,我尽可能地减少它,只显示相关代码。显示的每一行代码都与我的问题有关。 Reproducible 需要一个完整的 GNURadio 设置和测试方法,我认为它比任何人都想尝试的更冗长和努力。我需要一个具体的更改示例来了解您要查找的内容。谢谢!
标签: c++ sockets networking boost boost-asio