summaryrefslogtreecommitdiff
path: root/sys/src/cmd/aquarela/nbdgramconv.c
blob: 5cea1d63735bd2fb193ada7aad7640bc8ca6e9cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <u.h>
#include <libc.h>
#include <ip.h>
#include <thread.h>
#include "netbios.h"

int
nbdgramconvM2S(NbDgram *s, uchar *ap, uchar *ep)
{
	uchar *p = ap;
	int n;
	ushort length;

	if (ap + 6 + IPv4addrlen > ep)
		return 0;
	s->type = *p++;
	s->flags = *p++;
	s->id = nhgets(p); p+= 2;
	v4tov6(s->srcip, p); p+= IPv4addrlen;
	s->srcport = nhgets(p); p += 2;
	switch (s->type) {
	case NbDgramDirectUnique:
	case NbDgramDirectGroup:
	case NbDgramBroadcast:
		if (p + 4 > ep)
			return 0;
		length = nhgets(p); p += 2;
		s->datagram.offset = nhgets(p); p += 2;
		if (p + length > ep)
			return 0;
		ep = p + length;
		n = nbnamedecode(p, p, ep, s->datagram.srcname);
		if (n == 0)
			return 0;
		p += n;
		n = nbnamedecode(p, p, ep, s->datagram.dstname);
		if (n == 0)
			return 0;
		p += n;
		s->datagram.data = p;
		s->datagram.length = ep - p;
		p = ep;
		break;
	case NbDgramError:
		if (p + 1 > ep)
			return 0;
		s->error.code = *p++;
		break;
	case NbDgramQueryRequest:
	case NbDgramPositiveQueryResponse:
	case NbDgramNegativeQueryResponse:
		n = nbnamedecode(p, p, ep, s->query.dstname);
		if (n == 0)
			return 0;
		p += n;
		break;
	default:
		return 0;
	}
	return p - ap;
}

int
nbdgramconvS2M(uchar *ap, uchar *ep, NbDgram *s)
{
	uchar *p = ap;
	uchar *fixup;
	int n;

	if (p + 6 + IPv4addrlen > ep)
		return 0;
	*p++ = s->type;
	*p++ = s->flags;
	hnputs(p, s->id); p+= 2;
	v6tov4(p, s->srcip); p += IPv4addrlen;
	hnputs(p, s->srcport); p+= 2;
	switch (s->type) {
	case NbDgramDirectUnique:
	case NbDgramDirectGroup:
	case NbDgramBroadcast:
		if (p + 4 > ep)
			return 0;
		fixup = p;
		hnputs(p, s->datagram.length); p += 2;
		hnputs(p, s->datagram.offset); p += 2;
		n = nbnameencode(p, ep, s->datagram.srcname);
		if (n == 0)
			return 0;
		p += n;
		n = nbnameencode(p, ep, s->datagram.dstname);
		if (n == 0)
			return 0;
		p += n;
		if (p + s->datagram.length > ep)
			return 0;
		memcpy(p, s->datagram.data, s->datagram.length); p += s->datagram.length;
		hnputs(fixup, p - fixup - 4);
		break;
	case NbDgramError:
		if (p + 1 > ep)
			return 0;
		*p++ = s->error.code;
		break;
	case NbDgramQueryRequest:
	case NbDgramPositiveQueryResponse:
	case NbDgramNegativeQueryResponse:
		n = nbnameencode(p, ep, s->datagram.dstname);
		if (n == 0)
			return 0;
		p += n;
		break;
	default:
		return 0;
	}
	return p - ap;
}