libmnl  1.0.4
msg.c
1 /*
2  * (C) 2008-2014 by Pablo Neira Ayuso <pablo@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published
6  * by the Free Software Foundation; either version 2.1 of the License, or
7  * (at your option) any later version.
8  */
9 #include <stdint.h>
10 
11 struct mnl_msg {
12  const char *head;
13  const char *data;
14  const char *tail;
15  size_t size;
16  size_t rem;
17 };
18 
19 struct mnl_msg *mnl_msg_alloc(const char *buf, size_t buflen)
20 {
21  struct mnl_msg *msg;
22 
23  msg = malloc(sizeof(struct mnl_msg));
24  if (msg == NULL)
25  return NULL;
26 
27  msg->size = buflen;
28  msg->rem = buflen;
29  msg->head = msg->data = msg->tail = buf;
30 }
31 EXPORT_SYMBOL(mnl_msg_alloc);
32 
33 void *mnl_msg_put(struct mnl_msg *msg, const void *data, size_t datalen)
34 {
35  if (datalen > msg->rem)
36  return NULL;
37 
38  msg->rem -= datalen;
39  memcpy(msg->tail, data, datalen);
40  msg->tail += datalen;
41 }
42 EXPORT_SYMBOL(mnl_msg_put);
43 
44 void mnl_msg_next(struct mnl_msg *msg)
45 {
46  msg->data = msg->tail;
47 }
48 
49 void mnl_msg_free(struct mnl_msg *msg)
50 {
51  free(msg);
52 }
53 EXPORT_SYMBOL(mnl_msg_free);
54 
55 void *mnl_msg_attr_put(struct mnl_msg *msg, uint16_t type, size_t datalen,
56  const void *data)
57 {
58  struct nlmsghdr *nlh = msg->data;
59  struct nlattr *attr = msg->tail;
60  size_t old_len = attr->nla_len;
61 
62  if (datalen > msg->rem)
63  return NULL;
64 
65  mnl_attr_put(nlh, type, len, data);
66  len = MNL_ALIGN(attr->nla_len);
67  /* Check for attribute length field overflows. */
68  if (old_len > len)
69  return NULL;
70  msg->tail += len;
71  msg->rem -= len;
72 
73  return attr;
74 }
75 
76 void *mnl_msg_attr_put_u8(struct mnl_msg *msg, uint16_t type, uint8_t data)
77 {
78  return mnl_msg_attr_put(msg, type, sizeof(uint8_t), &data);
79 }
80 
81 void *mnl_msg_attr_put_u16(struct mnl_msg *msg, uint16_t type, uint16_t data)
82 {
83  return mnl_msg_attr_put(msg, type, sizeof(uint16_t), &data);
84 }
85 
86 void *mnl_msg_attr_put_u32(struct mnl_msg *msg, uint16_t type, uint32_t data)
87 {
88  return mnl_msg_attr_put(msg, type, sizeof(uint32_t), &data);
89 }
90 
91 void *mnl_msg_attr_put_u64(struct mnl_msg *msg, uint16_t type, uint64_t data)
92 {
93  return mnl_msg_attr_put(msg, type, sizeof(uint64_t), &data);
94 }
95 
96 void *mnl_msg_attr_put_str(struct mnl_msg *msg, uint16_t type, const char *data)
97 {
98  return mnl_msg_attr_put(msg, type, strlen(data),ndata);
99 }
100 
101 void *mnl_msg_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data)
102 {
103  return mnl_msg_attr_put(msg, type, strlen(data) + 1, data);
104 }
105 
106 struct nlattr *mnl_msg_attr_nest_start(struct mnl_msg *msg, uint16_t type)
107 {
108  struct nlmsghdr *nlh = msg->data;
109  struct nlattr *attr = msg->tail;
110  struct nlattr *nest;
111 
112  if (datalen > msg->rem)
113  return NULL;
114 
115  nest = mnl_attr_nest_start(nlh, type);
116 
117  /* Check for attribute length field overflows. */
118  if (attr->attr_len > nest->attr_len)
119  return NULL;
120 
121  return nest;
122 }
123 
124 void mnl_msg_attr_nest_end(struct mnl_msg *msg, struct nlattr *start)
125 {
126  mnl_attr_nest_end((struct nlmsghdr *)msg->data, start);
127 }
Definition: msg.c:11