GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/iked/imsg_util.c Lines: 12 63 19.0 %
Date: 2017-11-07 Branches: 4 36 11.1 %

Line Branch Exec Source
1
/*	$OpenBSD: imsg_util.c,v 1.11 2017/01/20 14:10:05 mikeb Exp $	*/
2
3
/*
4
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
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/queue.h>
20
#include <sys/socket.h>
21
#include <sys/uio.h>
22
23
#include <netdb.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <unistd.h>
27
#include <string.h>
28
#include <errno.h>
29
#include <fcntl.h>
30
#include <ctype.h>
31
#include <event.h>
32
33
#include "iked.h"
34
35
/*
36
 * Extending the imsg buffer API for internal use
37
 */
38
39
int
40
ibuf_cat(struct ibuf *dst, struct ibuf *src)
41
{
42
	return (ibuf_add(dst, src->buf, ibuf_size(src)));
43
}
44
45
void
46
ibuf_zero(struct ibuf *buf)
47
{
48
666871080
	explicit_bzero(buf->buf, buf->wpos);
49
333435540
}
50
51
struct ibuf *
52
ibuf_new(const void *data, size_t len)
53
{
54
	struct ibuf	*buf;
55
56
1000306620
	if ((buf = ibuf_dynamic(len,
57
333435540
	    IKED_MSGBUF_MAX)) == NULL)
58
		return (NULL);
59
60
333435540
	ibuf_zero(buf);
61
62
333435540
	if (data == NULL && len) {
63
		if (ibuf_advance(buf, len) == NULL) {
64
			ibuf_free(buf);
65
			return (NULL);
66
		}
67
	} else {
68
333435540
		if (ibuf_add(buf, data, len) != 0) {
69
			ibuf_free(buf);
70
			return (NULL);
71
		}
72
	}
73
74
333435540
	return (buf);
75
333435540
}
76
77
struct ibuf *
78
ibuf_static(void)
79
{
80
	struct ibuf	*buf;
81
82
	if ((buf = ibuf_open(IKED_MSGBUF_MAX)) == NULL)
83
		return (NULL);
84
85
	ibuf_zero(buf);
86
87
	return (buf);
88
}
89
90
void *
91
ibuf_advance(struct ibuf *buf, size_t len)
92
{
93
	void	*ptr;
94
95
	if ((ptr = ibuf_reserve(buf, len)) != NULL)
96
		memset(ptr, 0, len);
97
98
	return (ptr);
99
}
100
101
void
102
ibuf_release(struct ibuf *buf)
103
{
104
136680
	if (buf == NULL)
105
		return;
106
	if (buf->buf != NULL) {
107
		ibuf_zero(buf);
108
		free(buf->buf);
109
	}
110
	free(buf);
111
68340
}
112
113
size_t
114
ibuf_length(struct ibuf *buf)
115
{
116
	if (buf == NULL || buf->buf == NULL)
117
		return (0);
118
	return (ibuf_size(buf));
119
}
120
121
uint8_t *
122
ibuf_data(struct ibuf *buf)
123
{
124
11017261660
	return (ibuf_seek(buf, 0, 0));
125
}
126
127
void *
128
ibuf_getdata(struct ibuf *buf, size_t len)
129
{
130
	void	*data;
131
132
	if ((data = ibuf_seek(buf, buf->rpos, len)) == NULL)
133
		return (NULL);
134
	buf->rpos += len;
135
136
	return (data);
137
}
138
139
struct ibuf *
140
ibuf_get(struct ibuf *buf, size_t len)
141
{
142
	void		*data;
143
144
	if ((data = ibuf_getdata(buf, len)) == NULL)
145
		return (NULL);
146
147
	return (ibuf_new(data, len));
148
}
149
150
struct ibuf *
151
ibuf_dup(struct ibuf *buf)
152
{
153
	if (buf == NULL)
154
		return (NULL);
155
	return (ibuf_new(ibuf_data(buf), ibuf_size(buf)));
156
}
157
158
struct ibuf *
159
ibuf_random(size_t len)
160
{
161
	struct ibuf	*buf;
162
	void		*ptr;
163
164
	if ((buf = ibuf_open(len)) == NULL)
165
		return (NULL);
166
	if ((ptr = ibuf_reserve(buf, len)) == NULL) {
167
		ibuf_free(buf);
168
		return (NULL);
169
	}
170
	arc4random_buf(ptr, len);
171
	return (buf);
172
}
173
174
int
175
ibuf_setsize(struct ibuf *buf, size_t len)
176
{
177
	if (len > buf->size)
178
		return (-1);
179
	buf->wpos = len;
180
	return (0);
181
}
182
183
int
184
ibuf_prepend(struct ibuf *buf, void *data, size_t len)
185
{
186
	struct ibuf	*new;
187
188
	/* Swap buffers (we could also use memmove here) */
189
	if ((new = ibuf_new(data, len)) == NULL)
190
		return (-1);
191
	if (ibuf_cat(new, buf) == -1) {
192
		ibuf_release(new);
193
		return (-1);
194
	}
195
	free(buf->buf);
196
	memcpy(buf, new, sizeof(*buf));
197
	free(new);
198
199
	return (0);
200
}