xref: /openbsd/sbin/iked/imsg_util.c (revision 8932bfb7)
1 /*	$OpenBSD: imsg_util.c,v 1.4 2011/05/09 11:15:18 reyk Exp $	*/
2 
3 /*
4  * Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 #include <sys/queue.h>
21 #include <sys/socket.h>
22 #include <sys/uio.h>
23 
24 #include <net/if.h>
25 #include <netinet/in_systm.h>
26 #include <netinet/in.h>
27 #include <netinet/ip.h>
28 #include <netinet/tcp.h>
29 #include <arpa/inet.h>
30 #include <netdb.h>
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <ctype.h>
39 #include <event.h>
40 
41 #include "iked.h"
42 
43 /*
44  * Extending the imsg buffer API for internal use
45  */
46 
47 int
48 ibuf_cat(struct ibuf *dst, struct ibuf *src)
49 {
50 	return (ibuf_add(dst, src->buf, ibuf_size(src)));
51 }
52 
53 void
54 ibuf_zero(struct ibuf *buf)
55 {
56 	memset(buf->buf, 0, buf->wpos);
57 }
58 
59 struct ibuf *
60 ibuf_new(void *data, size_t len)
61 {
62 	struct ibuf	*buf;
63 
64 	if ((buf = ibuf_dynamic(len,
65 	    IKED_MSGBUF_MAX)) == NULL)
66 		return (NULL);
67 
68 	ibuf_zero(buf);
69 
70 	if (data == NULL && len) {
71 		if (ibuf_advance(buf, len) == NULL) {
72 			ibuf_free(buf);
73 			return (NULL);
74 		}
75 	} else {
76 		if (ibuf_add(buf, data, len) != 0) {
77 			ibuf_free(buf);
78 			return (NULL);
79 		}
80 	}
81 
82 	return (buf);
83 }
84 
85 struct ibuf *
86 ibuf_static(void)
87 {
88 	struct ibuf	*buf;
89 
90 	if ((buf = ibuf_open(IKED_MSGBUF_MAX)) == NULL)
91 		return (NULL);
92 
93 	ibuf_zero(buf);
94 
95 	return (buf);
96 }
97 
98 void *
99 ibuf_advance(struct ibuf *buf, size_t len)
100 {
101 	void	*ptr;
102 
103 	if ((ptr = ibuf_reserve(buf, len)) != NULL)
104 		memset(ptr, 0, len);
105 
106 	return (ptr);
107 }
108 
109 void
110 ibuf_release(struct ibuf *buf)
111 {
112 	if (buf == NULL)
113 		return;
114 	if (buf->buf != NULL)
115 		free(buf->buf);
116 	free(buf);
117 }
118 
119 size_t
120 ibuf_length(struct ibuf *buf)
121 {
122 	if (buf == NULL || buf->buf == NULL)
123 		return (0);
124 	return (ibuf_size(buf));
125 }
126 
127 u_int8_t *
128 ibuf_data(struct ibuf *buf)
129 {
130 	return (ibuf_seek(buf, 0, 0));
131 }
132 
133 void *
134 ibuf_getdata(struct ibuf *buf, size_t len)
135 {
136 	void	*data;
137 
138 	if ((data = ibuf_seek(buf, buf->rpos, len)) == NULL)
139 		return (NULL);
140 	buf->rpos += len;
141 
142 	return (data);
143 }
144 
145 struct ibuf *
146 ibuf_get(struct ibuf *buf, size_t len)
147 {
148 	void		*data;
149 
150 	if ((data = ibuf_getdata(buf, len)) == NULL)
151 		return (NULL);
152 
153 	return (ibuf_new(data, len));
154 }
155 
156 struct ibuf *
157 ibuf_dup(struct ibuf *buf)
158 {
159 	if (buf == NULL)
160 		return (NULL);
161 	return (ibuf_new(ibuf_data(buf), ibuf_size(buf)));
162 }
163 
164 struct ibuf *
165 ibuf_random(size_t len)
166 {
167 	struct ibuf	*buf;
168 	void		*ptr;
169 
170 	if ((buf = ibuf_open(len)) == NULL)
171 		return (NULL);
172 	if ((ptr = ibuf_reserve(buf, len)) == NULL) {
173 		ibuf_free(buf);
174 		return (NULL);
175 	}
176 	arc4random_buf(ptr, len);
177 	return (buf);
178 }
179 
180 int
181 ibuf_setsize(struct ibuf *buf, size_t len)
182 {
183 	if (len > buf->size)
184 		return (-1);
185 	buf->wpos = len;
186 	return (0);
187 }
188 
189 int
190 ibuf_prepend(struct ibuf *buf, void *data, size_t len)
191 {
192 	struct ibuf	*new;
193 
194 	/* Swap buffers (we could also use memmove here) */
195 	if ((new = ibuf_new(data, len)) == NULL)
196 		return (-1);
197 	if (ibuf_cat(new, buf) == -1) {
198 		ibuf_release(new);
199 		return (-1);
200 	}
201 	free(buf->buf);
202 	memcpy(buf, new, sizeof(*buf));
203 	free(new);
204 
205 	return (0);
206 }
207