From patchwork Wed May 20 11:33:52 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 5375 Received: from mail.gmx.net (mail.gmx.net [213.165.64.20]) by open-mesh.net (8.14.3/8.13.4/Debian-3sarge3) with SMTP id n4KBo9mL012993 for ; Wed, 20 May 2009 11:50:10 GMT Received: (qmail invoked by alias); 20 May 2009 11:34:11 -0000 Received: from i59F6BD09.versanet.de (EHLO localhost) [89.246.189.9] by mail.gmx.net (mp025) with SMTP; 20 May 2009 13:34:11 +0200 X-Authenticated: #15668376 X-Provags-ID: V01U2FsdGVkX1/b9PFWbozbwJTvtlX1S/sAgjA4Cy3GDm0JvdgiCQ ME8J+PC4LqIo9F From: Sven Eckelmann To: b.a.t.m.a.n@open-mesh.net Date: Wed, 20 May 2009 13:33:52 +0200 Message-Id: <1242819232-614-3-git-send-email-sven.eckelmann@gmx.de> X-Mailer: git-send-email 1.6.3.1 In-Reply-To: <1242819232-614-1-git-send-email-sven.eckelmann@gmx.de> References: <1242819232-614-1-git-send-email-sven.eckelmann@gmx.de> X-Y-GMX-Trusted: 0 X-FuHaFi: 0.42 Subject: [B.A.T.M.A.N.] [PATCH 2/2] [batman] Don't add size for netlink header twice in netlink request X-BeenThere: b.a.t.m.a.n@open-mesh.net X-Mailman-Version: 2.1.11 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 May 2009 11:50:10 -0000 The parameter len of NLMSG_LENGTH is only the size of the payload of the request. If we use this function to calculate the size of the buffer we send to the kernel we would add (sizeof(nlmsghdr)+padding) and the size of our own structure which also has a nlmsghdr included. We must split the req structure into a header part and the payload to calculate the correct size of our buffer and having the payload always start at the correct address. Signed-off-by: Sven Eckelmann --- batman/linux/route.c | 59 ++++++++++++++++++++++++++----------------------- 1 files changed, 31 insertions(+), 28 deletions(-) diff --git a/batman/linux/route.c b/batman/linux/route.c index 3ddce2e..4be0179 100644 --- a/batman/linux/route.c +++ b/batman/linux/route.c @@ -182,8 +182,8 @@ void add_del_route(uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src struct iovec iov; struct msghdr msg; struct nlmsghdr *nh; + struct nlmsghdr *nlh; struct req_s { - struct nlmsghdr nlh; struct rtmsg rtm; char buff[4 * (sizeof(struct rtattr) + 4)]; } *req; @@ -228,9 +228,10 @@ void add_del_route(uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src } - req = (struct req_s*)req_buf; + nlh = (struct nlmsghdr *)req_buf; + req = (struct req_s*)NLMSG_DATA(req_buf); memset(&nladdr, 0, sizeof(struct sockaddr_nl)); - memset(req, 0, NLMSG_LENGTH(sizeof(struct req_s))); + memset(req_buf, 0, NLMSG_LENGTH(sizeof(struct req_s))); memset(&msg, 0, sizeof(struct msghdr)); nladdr.nl_family = AF_NETLINK; @@ -244,22 +245,22 @@ void add_del_route(uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src if (src_ip != 0) len += sizeof(struct rtattr) + 4; - req->nlh.nlmsg_len = NLMSG_LENGTH(len); - req->nlh.nlmsg_pid = getpid(); + nlh->nlmsg_len = NLMSG_LENGTH(len); + nlh->nlmsg_pid = getpid(); req->rtm.rtm_family = AF_INET; req->rtm.rtm_table = rt_table; req->rtm.rtm_dst_len = netmask; if (route_action == ROUTE_DEL) { - req->nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - req->nlh.nlmsg_type = RTM_DELROUTE; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + nlh->nlmsg_type = RTM_DELROUTE; req->rtm.rtm_scope = RT_SCOPE_NOWHERE; } else { - req->nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_APPEND; - req->nlh.nlmsg_type = RTM_NEWROUTE; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_APPEND; + nlh->nlmsg_type = RTM_NEWROUTE; if (route_type == ROUTE_TYPE_UNICAST && my_router == 0 && src_ip != 0) req->rtm.rtm_scope = RT_SCOPE_LINK; @@ -317,7 +318,7 @@ void add_del_route(uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src } - if (sendto(netlink_sock, req, req->nlh.nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl)) < 0) { + if (sendto(netlink_sock, req_buf, nlh->nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl)) < 0) { debug_output(0, "Error - can't send message to kernel via netlink socket for routing table manipulation: %s\n", strerror(errno)); close(netlink_sock); @@ -366,8 +367,8 @@ void add_del_rule(uint32_t network, uint8_t netmask, int8_t rt_table, uint32_t p struct iovec iov; struct msghdr msg; struct nlmsghdr *nh; + struct nlmsghdr *nlh; struct req_s { - struct nlmsghdr nlh; struct rtmsg rtm; char buff[2 * (sizeof(struct rtattr) + 4)]; } *req; @@ -385,9 +386,10 @@ void add_del_rule(uint32_t network, uint8_t netmask, int8_t rt_table, uint32_t p } - req = (struct req_s*)req_buf; + nlh = (struct nlmsghdr *)req_buf; + req = (struct req_s*)NLMSG_DATA(req_buf); memset(&nladdr, 0, sizeof(struct sockaddr_nl)); - memset(req, 0, NLMSG_LENGTH(sizeof(struct req_s))); + memset(req_buf, 0, NLMSG_LENGTH(sizeof(struct req_s))); memset(&msg, 0, sizeof(struct msghdr)); nladdr.nl_family = AF_NETLINK; @@ -397,22 +399,22 @@ void add_del_rule(uint32_t network, uint8_t netmask, int8_t rt_table, uint32_t p if (prio != 0) len += sizeof(struct rtattr) + 4; - req->nlh.nlmsg_len = NLMSG_LENGTH(len); - req->nlh.nlmsg_pid = getpid(); + nlh->nlmsg_len = NLMSG_LENGTH(len); + nlh->nlmsg_pid = getpid(); req->rtm.rtm_family = AF_INET; req->rtm.rtm_table = rt_table; if (rule_action == RULE_DEL) { - req->nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - req->nlh.nlmsg_type = RTM_DELRULE; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + nlh->nlmsg_type = RTM_DELRULE; req->rtm.rtm_scope = RT_SCOPE_NOWHERE; } else { - req->nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL; - req->nlh.nlmsg_type = RTM_NEWRULE; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL; + nlh->nlmsg_type = RTM_NEWRULE; req->rtm.rtm_scope = RT_SCOPE_UNIVERSE; req->rtm.rtm_protocol = RTPROT_STATIC; req->rtm.rtm_type = RTN_UNICAST; @@ -467,7 +469,7 @@ void add_del_rule(uint32_t network, uint8_t netmask, int8_t rt_table, uint32_t p } - if (sendto(netlink_sock, req, req->nlh.nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl)) < 0) { + if (sendto(netlink_sock, req_buf, nlh->nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl)) < 0) { debug_output( 0, "Error - can't send message to kernel via netlink socket for routing rule manipulation: %s\n", strerror(errno)); close(netlink_sock); @@ -632,8 +634,8 @@ int flush_routes_rules(int8_t is_rule) struct msghdr msg; struct nlmsghdr *nh; struct rtmsg *rtm; + struct nlmsghdr *nlh; struct req_s { - struct nlmsghdr nlh; struct rtmsg rtm; } *req; char req_buf[NLMSG_LENGTH(sizeof(struct req_s))]; @@ -643,19 +645,20 @@ int flush_routes_rules(int8_t is_rule) iov.iov_base = buf; iov.iov_len = sizeof(buf); - req = (struct req_s*)req_buf; + nlh = (struct nlmsghdr *)req_buf; + req = (struct req_s*)NLMSG_DATA(req_buf); memset(&nladdr, 0, sizeof(struct sockaddr_nl)); - memset(req, 0, NLMSG_LENGTH(sizeof(struct req_s))); + memset(req_buf, 0, NLMSG_LENGTH(sizeof(struct req_s))); memset(&msg, 0, sizeof(struct msghdr)); nladdr.nl_family = AF_NETLINK; - req->nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct req_s)); - req->nlh.nlmsg_pid = getpid(); + nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct req_s)); + nlh->nlmsg_pid = getpid(); req->rtm.rtm_family = AF_INET; - req->nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; - req->nlh.nlmsg_type = (is_rule ? RTM_GETRULE : RTM_GETROUTE); + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; + nlh->nlmsg_type = (is_rule ? RTM_GETRULE : RTM_GETROUTE); req->rtm.rtm_scope = RTN_UNICAST; if ((netlink_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) { @@ -666,7 +669,7 @@ int flush_routes_rules(int8_t is_rule) } - if (sendto(netlink_sock, req, req->nlh.nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl)) < 0) { + if (sendto(netlink_sock, req_buf, nlh->nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl)) < 0) { debug_output(0, "Error - can't send message to kernel via netlink socket for flushing the routing table: %s\n", strerror(errno)); close(netlink_sock);