View | Details | Raw Unified | Return to bug 2735 | Differences between
and this patch

Collapse All | Expand All

(-)a/openbsd-compat/port-tun.c (-43 / +43 lines)
Lines 199-247 sys_tun_open(int tun, int mode) Link Here
199
 */
199
 */
200
200
201
#if defined(SSH_TUN_FILTER)
201
#if defined(SSH_TUN_FILTER)
202
/*
203
 * The tunnel forwarding protocol prepends the address family of forwarded
204
 * IP packets using OpenBSD's numbers.
205
 */
202
#define OPENBSD_AF_INET		2
206
#define OPENBSD_AF_INET		2
203
#define OPENBSD_AF_INET6	24
207
#define OPENBSD_AF_INET6	24
204
208
205
int
209
int
206
sys_tun_infilter(struct Channel *c, char *buf, int len)
210
sys_tun_infilter(struct Channel *c, char *buf, int _len)
207
{
211
{
208
#if defined(SSH_TUN_PREPEND_AF)
212
	int r;
209
	char rbuf[CHAN_RBUF];
213
	size_t len;
210
	struct ip *iph;
211
#endif
212
	u_int32_t *af;
213
	char *ptr = buf;
214
	char *ptr = buf;
214
	int r;
215
216
#if defined(SSH_TUN_PREPEND_AF)
215
#if defined(SSH_TUN_PREPEND_AF)
217
	if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af)))
216
	char rbuf[CHAN_RBUF];
218
		return (-1);
217
	struct ip iph;
219
	ptr = (char *)&rbuf[0];
218
#endif
220
	bcopy(buf, ptr + sizeof(u_int32_t), len);
219
#if defined(SSH_TUN_PREPEND_AF) || defined(SSH_TUN_COMPAT_AF)
221
	len += sizeof(u_int32_t);
220
	u_int32_t af;
222
	af = (u_int32_t *)ptr;
223
224
	iph = (struct ip *)(ptr + sizeof(u_int32_t));
225
	switch (iph->ip_v) {
226
	case 6:
227
		*af = AF_INET6;
228
		break;
229
	case 4:
230
	default:
231
		*af = AF_INET;
232
		break;
233
	}
234
#endif
221
#endif
235
222
236
#if defined(SSH_TUN_COMPAT_AF)
223
	/* XXX update channel input filter API to use unsigned length */
237
	if (len < (int)sizeof(u_int32_t))
224
	if (_len < 0)
238
		return (-1);
225
		return -1;
226
	len = _len;
239
227
240
	af = (u_int32_t *)ptr;
228
#if defined(SSH_TUN_PREPEND_AF)
241
	if (*af == htonl(AF_INET6))
229
	if (len <= sizeof(iph) || len > sizeof(rbuf) - 4)
242
		*af = htonl(OPENBSD_AF_INET6);
230
		return -1;
243
	else
231
	/* Determine address family from packet IP header. */
244
		*af = htonl(OPENBSD_AF_INET);
232
	memcpy(&iph, buf, sizeof(iph));
233
	af = iph.ip_v == 6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET;
234
	/* Prepend address family to packet using OpenBSD constants */
235
	memcpy(rbuf + 4, buf, len);
236
	len += 4;
237
	POKE_U32(rbuf, htonl(af));
238
	ptr = rbuf;
239
#elif defined(SSH_TUN_COMPAT_AF)
240
	/* Convert existing address family header to OpenBSD value */
241
	if (len <= 4)
242
		return -1;
243
	af = ntohl(PEEK_U32(buf));
244
	/* Put it back */
245
	POKE_U32(buf, htonl(af == AF_INET6 ?
246
	    OPENBSD_AF_INET6 : OPENBSD_AF_INET));
245
#endif
247
#endif
246
248
247
	if ((r = sshbuf_put_string(&c->input, ptr, len)) != 0)
249
	if ((r = sshbuf_put_string(&c->input, ptr, len)) != 0)
Lines 253-259 u_char * Link Here
253
sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen)
255
sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen)
254
{
256
{
255
	u_char *buf;
257
	u_char *buf;
256
	u_int32_t *af;
258
	u_int32_t af;
257
	int r;
259
	int r;
258
	size_t xxx_dlen;
260
	size_t xxx_dlen;
259
261
Lines 262-282 sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen) Link Here
262
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
264
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
263
	if (dlen != NULL)
265
	if (dlen != NULL)
264
		*dlen = xxx_dlen;
266
		*dlen = xxx_dlen;
265
	if (*dlen < sizeof(*af))
267
	if (*dlen < sizeof(af))
266
		return (NULL);
268
		return (NULL);
267
	buf = *data;
269
	buf = *data;
268
270
269
#if defined(SSH_TUN_PREPEND_AF)
271
#if defined(SSH_TUN_PREPEND_AF)
270
	*dlen -= sizeof(u_int32_t);
272
	/* skip address family */
271
	buf = *data + sizeof(u_int32_t);
273
	*dlen -= sizeof(af);
274
	buf = *data + sizeof(af);
272
#elif defined(SSH_TUN_COMPAT_AF)
275
#elif defined(SSH_TUN_COMPAT_AF)
273
	af = ntohl(*(u_int32_t *)buf);
276
	/* translate address family */
274
	if (*af == OPENBSD_AF_INET6)
277
	af = (ntohl(PEEK_U32(buf)) == OPENBSD_AF_INET6) ? AF_INET6 : AF_INET;
275
		*af = htonl(AF_INET6);
278
	POKE_U32(buf, htonl(af));
276
	else
277
		*af = htonl(AF_INET);
278
#endif
279
#endif
279
280
	return (buf);
280
	return (buf);
281
}
281
}
282
#endif /* SSH_TUN_FILTER */
282
#endif /* SSH_TUN_FILTER */

Return to bug 2735