1 /* $OpenBSD: imsg_util.c,v 1.17 2023/05/30 08:41:15 claudio 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 struct ibuf * 46 ibuf_new(const void *data, size_t len) 47 { 48 struct ibuf *buf; 49 50 if ((buf = ibuf_dynamic(len, 51 IKED_MSGBUF_MAX)) == NULL) 52 return (NULL); 53 54 if (len == 0) 55 return (buf); 56 57 if (data == NULL) { 58 if (ibuf_reserve(buf, len) == NULL) { 59 ibuf_free(buf); 60 return (NULL); 61 } 62 } else { 63 if (ibuf_add(buf, data, len) != 0) { 64 ibuf_free(buf); 65 return (NULL); 66 } 67 } 68 69 return (buf); 70 } 71 72 struct ibuf * 73 ibuf_static(void) 74 { 75 return ibuf_open(IKED_MSGBUF_MAX); 76 } 77 78 size_t 79 ibuf_length(struct ibuf *buf) 80 { 81 if (buf == NULL || buf->buf == NULL) 82 return (0); 83 return (ibuf_size(buf)); 84 } 85 86 uint8_t * 87 ibuf_data(struct ibuf *buf) 88 { 89 return (ibuf_seek(buf, 0, 0)); 90 } 91 92 void * 93 ibuf_getdata(struct ibuf *buf, size_t len) 94 { 95 void *data; 96 97 if ((data = ibuf_seek(buf, buf->rpos, len)) == NULL) 98 return (NULL); 99 buf->rpos += len; 100 101 return (data); 102 } 103 104 struct ibuf * 105 ibuf_get(struct ibuf *buf, size_t len) 106 { 107 void *data; 108 109 if ((data = ibuf_getdata(buf, len)) == NULL) 110 return (NULL); 111 112 return (ibuf_new(data, len)); 113 } 114 115 struct ibuf * 116 ibuf_dup(struct ibuf *buf) 117 { 118 if (buf == NULL) 119 return (NULL); 120 return (ibuf_new(ibuf_data(buf), ibuf_size(buf))); 121 } 122 123 struct ibuf * 124 ibuf_random(size_t len) 125 { 126 struct ibuf *buf; 127 void *ptr; 128 129 if ((buf = ibuf_open(len)) == NULL) 130 return (NULL); 131 if ((ptr = ibuf_reserve(buf, len)) == NULL) { 132 ibuf_free(buf); 133 return (NULL); 134 } 135 arc4random_buf(ptr, len); 136 return (buf); 137 } 138 139 int 140 ibuf_setsize(struct ibuf *buf, size_t len) 141 { 142 if (len > buf->size) 143 return (-1); 144 buf->wpos = len; 145 return (0); 146 } 147 148 int 149 ibuf_strcat(struct ibuf **buf, const char *s) 150 { 151 size_t slen; 152 153 if (buf == NULL) 154 return (-1); 155 slen = strlen(s); 156 if (*buf == NULL) { 157 if ((*buf = ibuf_new(s, slen)) == NULL) 158 return (-1); 159 return (0); 160 } 161 return (ibuf_add(*buf, s, slen)); 162 } 163 164 int 165 ibuf_strlen(struct ibuf *buf) 166 { 167 if (ibuf_length(buf) > INT_MAX) 168 return (INT_MAX); 169 return ((int)ibuf_length(buf)); 170 } 171