Blame


1 f024663d 2021-09-05 stsp /*
2 f024663d 2021-09-05 stsp * Copyright (c) 2019 Ori Bernstein <ori@openbsd.org>
3 f024663d 2021-09-05 stsp * Copyright (c) 2021 Stefan Sperling <stsp@openbsd.org>
4 f024663d 2021-09-05 stsp *
5 f024663d 2021-09-05 stsp * Permission to use, copy, modify, and distribute this software for any
6 f024663d 2021-09-05 stsp * purpose with or without fee is hereby granted, provided that the above
7 f024663d 2021-09-05 stsp * copyright notice and this permission notice appear in all copies.
8 f024663d 2021-09-05 stsp *
9 f024663d 2021-09-05 stsp * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 f024663d 2021-09-05 stsp * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 f024663d 2021-09-05 stsp * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 f024663d 2021-09-05 stsp * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 f024663d 2021-09-05 stsp * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 f024663d 2021-09-05 stsp * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 f024663d 2021-09-05 stsp * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 f024663d 2021-09-05 stsp */
17 f024663d 2021-09-05 stsp
18 f024663d 2021-09-05 stsp #include <ctype.h>
19 f024663d 2021-09-05 stsp #include <errno.h>
20 f024663d 2021-09-05 stsp #include <limits.h>
21 f024663d 2021-09-05 stsp #include <stdio.h>
22 f024663d 2021-09-05 stsp #include <stdlib.h>
23 f024663d 2021-09-05 stsp #include <unistd.h>
24 f024663d 2021-09-05 stsp
25 f024663d 2021-09-05 stsp #include "got_error.h"
26 336075a4 2022-06-25 op #include "got_lib_pkt.h"
27 6fefa431 2024-05-05 stsp #include "got_lib_poll.h"
28 f024663d 2021-09-05 stsp
29 f024663d 2021-09-05 stsp const struct got_error *
30 0fb910a4 2024-05-05 stsp got_pkt_readn(ssize_t *off, int fd, void *buf, size_t n,
31 0fb910a4 2024-05-05 stsp int timeout)
32 f024663d 2021-09-05 stsp {
33 6fefa431 2024-05-05 stsp const struct got_error *err;
34 6fefa431 2024-05-05 stsp size_t len;
35 f024663d 2021-09-05 stsp
36 6fefa431 2024-05-05 stsp err = got_poll_read_full_timeout(fd, &len, buf, n, n,
37 0fb910a4 2024-05-05 stsp timeout);
38 6fefa431 2024-05-05 stsp if (err)
39 6fefa431 2024-05-05 stsp return err;
40 6fefa431 2024-05-05 stsp
41 6fefa431 2024-05-05 stsp /* XXX size_t -> ssize_t */
42 6fefa431 2024-05-05 stsp if (len > SSIZE_MAX)
43 6fefa431 2024-05-05 stsp return got_error(GOT_ERR_RANGE);
44 6fefa431 2024-05-05 stsp *off = len;
45 f024663d 2021-09-05 stsp return NULL;
46 f024663d 2021-09-05 stsp }
47 f024663d 2021-09-05 stsp
48 f024663d 2021-09-05 stsp const struct got_error *
49 f024663d 2021-09-05 stsp got_pkt_flushpkt(int fd, int chattygot)
50 f024663d 2021-09-05 stsp {
51 f024663d 2021-09-05 stsp ssize_t w;
52 f024663d 2021-09-05 stsp
53 f024663d 2021-09-05 stsp if (chattygot > 1)
54 f024663d 2021-09-05 stsp fprintf(stderr, "%s: writepkt: 0000\n", getprogname());
55 f024663d 2021-09-05 stsp
56 f024663d 2021-09-05 stsp w = write(fd, "0000", 4);
57 f024663d 2021-09-05 stsp if (w == -1)
58 f024663d 2021-09-05 stsp return got_error_from_errno("write");
59 f024663d 2021-09-05 stsp if (w != 4)
60 f024663d 2021-09-05 stsp return got_error(GOT_ERR_IO);
61 f024663d 2021-09-05 stsp return NULL;
62 f024663d 2021-09-05 stsp }
63 f024663d 2021-09-05 stsp
64 b77bad15 2024-04-19 me const struct got_error *
65 b77bad15 2024-04-19 me got_pkt_readlen(int *len, const char *str, int chattygot)
66 b77bad15 2024-04-19 me {
67 b77bad15 2024-04-19 me int i;
68 b77bad15 2024-04-19 me
69 b77bad15 2024-04-19 me *len = 0;
70 b77bad15 2024-04-19 me for (i = 0; i < 4; i++) {
71 b77bad15 2024-04-19 me if ('0' <= str[i] && str[i] <= '9') {
72 b77bad15 2024-04-19 me *len *= 16;
73 b77bad15 2024-04-19 me *len += str[i] - '0';
74 b77bad15 2024-04-19 me } else if ('a' <= str[i] && str[i] <= 'f') {
75 b77bad15 2024-04-19 me *len *= 16;
76 b77bad15 2024-04-19 me *len += str[i] - 'a' + 10;
77 b77bad15 2024-04-19 me } else {
78 b77bad15 2024-04-19 me if (chattygot)
79 b77bad15 2024-04-19 me fprintf(stderr, "%s: bad length: '.4%s'\n",
80 b77bad15 2024-04-19 me getprogname(), str);
81 b77bad15 2024-04-19 me return got_error_msg(GOT_ERR_BAD_PACKET,
82 b77bad15 2024-04-19 me "packet length has invalid format");
83 b77bad15 2024-04-19 me }
84 b77bad15 2024-04-19 me }
85 b77bad15 2024-04-19 me return NULL;
86 b77bad15 2024-04-19 me }
87 b77bad15 2024-04-19 me
88 f024663d 2021-09-05 stsp /*
89 f024663d 2021-09-05 stsp * Packet header contains a 4-byte hexstring which specifies the length
90 f024663d 2021-09-05 stsp * of data which follows.
91 f024663d 2021-09-05 stsp */
92 f024663d 2021-09-05 stsp const struct got_error *
93 0fb910a4 2024-05-05 stsp got_pkt_readhdr(int *datalen, int fd, int chattygot, int timeout)
94 f024663d 2021-09-05 stsp {
95 b77bad15 2024-04-19 me static const struct got_error *err;
96 b77bad15 2024-04-19 me char lenstr[4];
97 f024663d 2021-09-05 stsp ssize_t r;
98 b77bad15 2024-04-19 me int n;
99 f024663d 2021-09-05 stsp
100 f024663d 2021-09-05 stsp *datalen = 0;
101 f024663d 2021-09-05 stsp
102 0fb910a4 2024-05-05 stsp err = got_pkt_readn(&r, fd, lenstr, 4, timeout);
103 f024663d 2021-09-05 stsp if (err)
104 f024663d 2021-09-05 stsp return err;
105 f024663d 2021-09-05 stsp if (r == 0) {
106 f024663d 2021-09-05 stsp /* implicit "0000" */
107 f024663d 2021-09-05 stsp if (chattygot > 1)
108 f024663d 2021-09-05 stsp fprintf(stderr, "%s: readpkt: 0000\n", getprogname());
109 f024663d 2021-09-05 stsp return NULL;
110 f024663d 2021-09-05 stsp }
111 f024663d 2021-09-05 stsp if (r != 4)
112 f024663d 2021-09-05 stsp return got_error_msg(GOT_ERR_BAD_PACKET,
113 f024663d 2021-09-05 stsp "wrong packet header length");
114 f024663d 2021-09-05 stsp
115 b77bad15 2024-04-19 me err = got_pkt_readlen(&n, lenstr, chattygot);
116 f024663d 2021-09-05 stsp if (n == 0)
117 b77bad15 2024-04-19 me return err;
118 f024663d 2021-09-05 stsp if (n <= 4)
119 f024663d 2021-09-05 stsp return got_error_msg(GOT_ERR_BAD_PACKET, "packet too short");
120 b77bad15 2024-04-19 me n -= 4;
121 f024663d 2021-09-05 stsp
122 f024663d 2021-09-05 stsp *datalen = n;
123 f024663d 2021-09-05 stsp return NULL;
124 f024663d 2021-09-05 stsp }
125 f024663d 2021-09-05 stsp
126 f024663d 2021-09-05 stsp const struct got_error *
127 0fb910a4 2024-05-05 stsp got_pkt_readpkt(int *outlen, int fd, char *buf, int buflen, int chattygot,
128 0fb910a4 2024-05-05 stsp int timeout)
129 f024663d 2021-09-05 stsp {
130 f024663d 2021-09-05 stsp const struct got_error *err = NULL;
131 f024663d 2021-09-05 stsp int datalen, i;
132 f024663d 2021-09-05 stsp ssize_t n;
133 f024663d 2021-09-05 stsp
134 0fb910a4 2024-05-05 stsp err = got_pkt_readhdr(&datalen, fd, chattygot, timeout);
135 f024663d 2021-09-05 stsp if (err)
136 f024663d 2021-09-05 stsp return err;
137 f024663d 2021-09-05 stsp
138 f024663d 2021-09-05 stsp if (datalen > buflen)
139 f024663d 2021-09-05 stsp return got_error(GOT_ERR_NO_SPACE);
140 f024663d 2021-09-05 stsp
141 0fb910a4 2024-05-05 stsp err = got_pkt_readn(&n, fd, buf, datalen, timeout);
142 f024663d 2021-09-05 stsp if (err)
143 f024663d 2021-09-05 stsp return err;
144 f024663d 2021-09-05 stsp if (n != datalen)
145 f024663d 2021-09-05 stsp return got_error_msg(GOT_ERR_BAD_PACKET, "short packet");
146 f024663d 2021-09-05 stsp
147 f024663d 2021-09-05 stsp if (chattygot > 1) {
148 f024663d 2021-09-05 stsp fprintf(stderr, "%s: readpkt: %zd:\t", getprogname(), n);
149 f024663d 2021-09-05 stsp for (i = 0; i < n; i++) {
150 99fd9ff4 2022-11-17 op if (isprint((unsigned char)buf[i]))
151 f024663d 2021-09-05 stsp fputc(buf[i], stderr);
152 f024663d 2021-09-05 stsp else
153 f024663d 2021-09-05 stsp fprintf(stderr, "[0x%.2x]", buf[i]);
154 f024663d 2021-09-05 stsp }
155 f024663d 2021-09-05 stsp fputc('\n', stderr);
156 f024663d 2021-09-05 stsp }
157 f024663d 2021-09-05 stsp
158 f024663d 2021-09-05 stsp *outlen = n;
159 f024663d 2021-09-05 stsp return NULL;
160 f024663d 2021-09-05 stsp }
161 f024663d 2021-09-05 stsp
162 f024663d 2021-09-05 stsp const struct got_error *
163 f024663d 2021-09-05 stsp got_pkt_writepkt(int fd, char *buf, int nbuf, int chattygot)
164 f024663d 2021-09-05 stsp {
165 f024663d 2021-09-05 stsp char len[5];
166 438d0cc3 2022-08-16 op int i, ret;
167 f024663d 2021-09-05 stsp ssize_t w;
168 f024663d 2021-09-05 stsp
169 438d0cc3 2022-08-16 op ret = snprintf(len, sizeof(len), "%04x", nbuf + 4);
170 438d0cc3 2022-08-16 op if (ret < 0 || (size_t)ret >= sizeof(len))
171 f024663d 2021-09-05 stsp return got_error(GOT_ERR_NO_SPACE);
172 f024663d 2021-09-05 stsp w = write(fd, len, 4);
173 f024663d 2021-09-05 stsp if (w == -1)
174 f024663d 2021-09-05 stsp return got_error_from_errno("write");
175 f024663d 2021-09-05 stsp if (w != 4)
176 f024663d 2021-09-05 stsp return got_error(GOT_ERR_IO);
177 f024663d 2021-09-05 stsp w = write(fd, buf, nbuf);
178 f024663d 2021-09-05 stsp if (w == -1)
179 f024663d 2021-09-05 stsp return got_error_from_errno("write");
180 f024663d 2021-09-05 stsp if (w != nbuf)
181 f024663d 2021-09-05 stsp return got_error(GOT_ERR_IO);
182 f024663d 2021-09-05 stsp if (chattygot > 1) {
183 f024663d 2021-09-05 stsp fprintf(stderr, "%s: writepkt: %s:\t", getprogname(), len);
184 f024663d 2021-09-05 stsp for (i = 0; i < nbuf; i++) {
185 99fd9ff4 2022-11-17 op if (isprint((unsigned char)buf[i]))
186 f024663d 2021-09-05 stsp fputc(buf[i], stderr);
187 f024663d 2021-09-05 stsp else
188 f024663d 2021-09-05 stsp fprintf(stderr, "[0x%.2x]", buf[i]);
189 f024663d 2021-09-05 stsp }
190 f024663d 2021-09-05 stsp fputc('\n', stderr);
191 f024663d 2021-09-05 stsp }
192 f024663d 2021-09-05 stsp return NULL;
193 f024663d 2021-09-05 stsp }