- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我编写了一个用户空间程序,应该在路由表中安装一个新路由。我注意到的是,如果 bytes sendmsg
fn 返回是正确的,但程序无法安装新路由。当我尝试在 Linux 内核上使用 gdb 诊断问题时,我发现垃圾数据正在从用户空间发送到内核 netlink 套接字。
输出
[root@localhost rtnetlink]# ./netlink_add_route.exe
bytes send = 52
分享代码:
typedef struct _request
{
struct nlmsghdr netlink_header;
struct rtmsg rt_message;
char buffer[1024];
} req_t;
int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
{
/* alen is the length of the data. Add sizeof(struct rtattr) to it to accomodate
type, length, value format for rtattr */
int len = RTA_LENGTH(alen); // (RTA_ALIGN(sizeof(struct rtattr)) + (len))
struct rtattr *rta;
/* size of request should not be violated*/
if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen)
return -1;
/* go to end of buffer in request data structure*/
rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
/* specify attribute using TLV format*/
rta->rta_type = type;
rta->rta_len = len;
memcpy(RTA_DATA(rta), data, alen);
/* increase the nlmsg_len to accomodate the added new attribute*/
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
return 0;
}
static void
initialisation(){
/* initialise the request structure*/
int index = 3,
gw = 3232236545/*192.168.4.1*/,
dst = 3232235776/*192.168.1.0*/;
memset(&request, 0, sizeof(request));
/* set the nlmsg_len = nl header + underlying structure*/
request.netlink_header.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); /*NLMSG_HDRLEN + sizeof(struct rtmsg);*/
/* set the flags that facilitates adding a route in routing table*/
request.netlink_header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE;
/* note that inet_rtm_newroute() is the fn in kernel which will be eventually called to add a new route in routing table*/
request.netlink_header.nlmsg_type = RTM_NEWROUTE;
/* Now filling the rtmsg*/
request.rt_message.rtm_family = AF_INET;
request.rt_message.rtm_table = RT_TABLE_MAIN;
request.rt_message.rtm_protocol = RTPROT_BOOT;/*Route installed during boot*/
request.rt_message.rtm_scope = RT_SCOPE_UNIVERSE;
request.rt_message.rtm_type = RTN_UNICAST; /*Gateway or direct route */
/* Add routing info*/
addattr_l(&request.netlink_header, sizeof(request), RTA_GATEWAY, &gw, sizeof(gw));
addattr_l(&request.netlink_header, sizeof(request), RTA_DST, &dst, sizeof(dst));
addattr_l(&request.netlink_header, sizeof(request), RTA_OIF, &index, sizeof(index));
/* For adding a route, the gateway, destination address and the interface
will suffice, now the netlink packet is all set to go to the kernel*/
}
static void
send_request(int fd){
int rc = 0;
struct msghdr msg;
struct sockaddr_nl nladdr;
struct iovec iov;
iov.iov_base = (void*)&request.netlink_header;
iov.iov_len = request.netlink_header.nlmsg_len ;/* Total length : from request start to end of last attribute*/
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
nladdr.nl_pid = 0; /* For Linux Kernel */
nladdr.nl_groups = 0;
msg.msg_name = (void *)&nladdr;
msg.msg_namelen = sizeof(nladdr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
rc = sendmsg(fd, &msg, 0);
printf("bytes send = %d\n", rc);
}
int
main(int argc, char *argv[])
{
struct sockaddr_nl la;
int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if(fd < 0){
printf("socket creation failed\n");
return -1;
}
bzero(&la, sizeof(la));
la.nl_family = AF_NETLINK;
la.nl_pid = getpid();
la.nl_groups = 0;
if(bind(fd, (struct sockaddr*) &la, sizeof(la)) < 0){
printf("Bind failed\n");
return -1;
}
initialisation();
send_request(fd);
close(fd);
}
gdb 输出
Breakpoint 1, inet_rtm_newroute (skb=0xbb53f20, nlh=0xb96ed00) at net/ipv4/fib_frontend.c:732
732 {
(gdb) bt
#0 inet_rtm_newroute (skb=0xbb53f20, nlh=0xb96ed00) at net/ipv4/fib_frontend.c:732
#1 0x081f1b28 in rtnetlink_rcv_msg (skb=0xbb53f20, nlh=0xb96ed00) at net/core/rtnetlink.c:3412
#2 0x081fcd07 in netlink_rcv_skb (skb=0xbb53f20, cb=0x81f19de <rtnetlink_rcv_msg>)
at net/netlink/af_netlink.c:3017
#3 0x081efcb9 in rtnetlink_rcv (skb=0xbb53f20) at net/core/rtnetlink.c:3418
#4 0x081fc7e4 in netlink_unicast_kernel (ssk=<optimized out>, skb=<optimized out>, sk=<optimized out>) at net/netlink/af_netlink.c:1834
#5 netlink_unicast (ssk=0xbb03000, skb=0xbb53f20, portid=0, nonblock=0) at net/netlink/af_netlink.c:1860
#6 0x081fcbf3 in netlink_sendmsg (sock=0xa50a700, msg=0xbb71e3c, len=52) at net/netlink/af_netlink.c:2511
#7 0x081cf181 in sock_sendmsg_nosec (msg=<optimized out>, sock=<optimized out>) at net/socket.c:611
#8 sock_sendmsg (sock=0xa50a700, msg=<optimized out>) at net/socket.c:621
#9 0x081cf781 in ___sys_sendmsg (sock=0xa50a700, msg=<optimized out>, msg_sys=0xbb71e3c, flags=0,
used_address=0x0) at net/socket.c:1947
#10 0x081d044f in __sys_sendmsg (fd=3, msg=0xbfd5cc40, flags=0) at net/socket.c:1981
#11 0x081d0a97 in SYSC_sendmsg (flags=<optimized out>, msg=<optimized out>, fd=<optimized out>)
at net/socket.c:1992
#12 SyS_sendmsg (flags=0, msg=-1076507584, fd=3) at net/socket.c:1988
#13 SYSC_socketcall (args=<optimized out>, call=<optimized out>) at net/socket.c:2397
#14 SyS_socketcall (call=16, args=-1076507632) at net/socket.c:2315
#15 0x0805ba59 in handle_syscall (r=0xbbab3f0) at arch/um/kernel/skas/syscall.c:37
#16 0x08069147 in handle_trap (local_using_sysemu=<optimized out>, regs=<optimized out>,
pid=<optimized out>) at arch/um/os-Linux/skas/process.c:172
#17 userspace (regs=0xbbab3f0) at arch/um/os-Linux/skas/process.c:384
#18 0x080594df in fork_handler () at arch/um/kernel/process.c:154
#19 0x00000000 in ?? ()
(gdb) f 6
#6 0x081fcbf3 in netlink_sendmsg (sock=0xa50a700, msg=0xbb71e3c, len=52) at net/netlink/af_netlink.c:2511
2511 err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT);
(gdb) p msg
$1 = (struct msghdr *) 0xbb71e3c
(gdb) p *(struct msghdr *) 0xbb71e3c
$2 = {msg_name = 0xbb71d98, msg_namelen = 12, msg_iter = {type = 1, iov_offset = 0, count = 0, {
iov = 0xbb71d60, kvec = 0xbb71d60, bvec = 0xbb71d60}, nr_segs = 0}, msg_control = 0x4,
msg_controllen = 0, msg_flags = 0, msg_iocb = 0x0}
(gdb) f 10
#10 0x081d044f in __sys_sendmsg (fd=3, msg=0xbfd5cc40, flags=0) at net/socket.c:1981
1981 err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
(gdb) p msg
$3 = (struct user_msghdr *) 0xbfd5cc40
(gdb) p *(struct user_msghdr *) 0xbfd5cc40
Cannot access memory at address 0xbfd5cc40
正如您在上面看到的,无法访问内核中收到的消息。当我在应用程序的 sendmsg fn 上应用 gdb 并扩展发送到内核的消息时,我发现一切都很完美。是什么导致用户空间和内核之间的消息损坏?任何人都可以帮助诊断问题吗?
我使用的是内核版本 4.5.3。
如果有人想运行该程序,请共享 src 文件的链接。 https://drive.google.com/file/d/0B56H_R1fVFZXRjNWRkZ3M09pY2s/view?usp=sharing
谢谢。
最佳答案
我可以成功地让它发挥作用。问题在于添加 RTA_DST 和 RTA_GATEWAY 的方式。您需要为 dst 使用 inet_prefix。请注意 dst.data[]、dst.bytelen 和 dst.bitlen 都是一些随机值。请根据您的解决方案的需要进行初始化。 (这只是为了证明它有效!)
typedef struct
{
__u16 flags;
__u16 bytelen;
__s16 bitlen;
__u16 family;
__u32 data[8];
} inet_prefix;
inet_prefix dst;
dst.data[0] = 11;
dst.data[1] = 12;
dst.data[2] = 13;
dst.data[3] = 14;
dst.data[4] = 15;
dst.data[5] = 16;
dst.data[6] = 17;
dst.data[7] = 17;
dst.bytelen = 32;
dst.bitlen = dst.bytelen * 8;
/* mask */
request.rt_message.rtm_dst_len = 24;
//addattr_l(&request.netlink_header, sizeof(request), RTA_GATEWAY, &gw, sizeof(gw));
addattr_l(&request.netlink_header, sizeof(request), RTA_DST, &dst, sizeof(dst));
作为示例,我添加了“dst”条目并注释掉了“gw”条目。对于“gw”,您也必须遵循类似的结构 inet_prefix。
条目创建:
12.0.32.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
关于linux - 使用 rtnetlink 套接字在 linux 路由表中安装新路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37465768/
我有一台 MySQL 服务器和一台 PostgreSQL 服务器。 需要从多个表中复制或重新插入一组数据 MySQL 流式传输/同步到 PostgreSQL 表。 这种复制可以基于时间(Sync)或事
如果两个表的 id 彼此相等,我尝试从一个表中获取数据。这是我使用的代码: SELECT id_to , email_to , name_to , status_to
我有一个 Excel 工作表。顶行对应于列名称,而连续的行每行代表一个条目。 如何将此 Excel 工作表转换为 SQL 表? 我使用的是 SQL Server 2005。 最佳答案 这取决于您使用哪
我想合并两个 Django 模型并创建一个模型。让我们假设我有第一个表表 A,其中包含一些列和数据。 Table A -------------- col1 col2 col3 col
我有两个表:table1,table2,如下所示 table1: id name 1 tamil 2 english 3 maths 4 science table2: p
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 1 年前。 Improve th
下面两个语句有什么区别? newTable = orginalTable 或 newTable.data(originalTable) 我怀疑 .data() 方法具有性能优势,因为它在标准 AX 中
我有一个表,我没有在其中显式定义主键,它并不是真正需要的功能......但是一位同事建议我添加一个列作为唯一主键以随着数据库的增长提高性能...... 谁能解释一下这是如何提高性能的? 没有使用索引(
如何将表“产品”中的产品记录与其不同表“图像”中的图像相关联? 我正在对产品 ID 使用自动增量。 我觉得不可能进行关联,因为产品 ID 是自动递增的,因此在插入期间不可用! 如何插入新产品,获取产品
我有一个 sql 表,其中包含关键字和出现次数,如下所示(尽管出现次数并不重要): ____________ dog | 3 | ____________ rat | 7 | ____
是否可以使用目标表中的LAST_INSERT_ID更新源表? INSERT INTO `target` SELECT `a`, `b` FROM `source` 目标表有一个自动增量键id,我想将其
我正在重建一个搜索查询,因为它在“我看到的”中变得多余,我想知道什么 (albums_artists, artists) ( ) does in join? is it for boosting pe
以下是我使用 mysqldump 备份数据库的开关: /usr/bin/mysqldump -u **** --password=**** --single-transaction --databas
我试图获取 MySQL 表中的所有行并将它们放入 HTML 表中: Exam ID Status Assigned Examiner
如何查询名为 photos 的表中的所有记录,并知道当前用户使用单个查询将哪些结果照片添加为书签? 这是我的表格: -- -- Table structure for table `photos` -
我的网站都在 InnoDB 表上运行,目前为止运行良好。现在我想知道在我的网站上实时发生了什么,所以我将每个页面浏览量(页面、引荐来源网址、IP、主机名等)存储在 InnoDB 表中。每秒大约有 10
我在想我会为 mysql 准备两个表。一个用于存储登录信息,另一个用于存储送货地址。这是传统方式还是所有内容都存储在一张表中? 对于两个表...有没有办法自动将表 A 的列复制到表 B,以便我可以引用
我不是程序员,我从这个表格中阅读了很多关于如何解决我的问题的内容,但我的搜索效果不好 我有两张 table 表 1:成员 id*| name | surname -------------------
我知道如何在 ASP.NET 中显示真实表,例如 public ActionResult Index() { var s = db.StaffInfoDBSet.ToList(); r
我正在尝试运行以下查询: "insert into visits set source = 'http://google.com' and country = 'en' and ref = '1234
我是一名优秀的程序员,十分优秀!