xref: /plan9/sys/src/cmd/aquarela/nbdgramconv.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include <thread.h>
5 #include "netbios.h"
6 
7 int
nbdgramconvM2S(NbDgram * s,uchar * ap,uchar * ep)8 nbdgramconvM2S(NbDgram *s, uchar *ap, uchar *ep)
9 {
10 	uchar *p = ap;
11 	int n;
12 	ushort length;
13 
14 	if (ap + 6 + IPv4addrlen > ep)
15 		return 0;
16 	s->type = *p++;
17 	s->flags = *p++;
18 	s->id = nhgets(p); p+= 2;
19 	v4tov6(s->srcip, p); p+= IPv4addrlen;
20 	s->srcport = nhgets(p); p += 2;
21 	switch (s->type) {
22 	case NbDgramDirectUnique:
23 	case NbDgramDirectGroup:
24 	case NbDgramBroadcast:
25 		if (p + 4 > ep)
26 			return 0;
27 		length = nhgets(p); p += 2;
28 		s->datagram.offset = nhgets(p); p += 2;
29 		if (p + length > ep)
30 			return 0;
31 		ep = p + length;
32 		n = nbnamedecode(p, p, ep, s->datagram.srcname);
33 		if (n == 0)
34 			return 0;
35 		p += n;
36 		n = nbnamedecode(p, p, ep, s->datagram.dstname);
37 		if (n == 0)
38 			return 0;
39 		p += n;
40 		s->datagram.data = p;
41 		s->datagram.length = ep - p;
42 		p = ep;
43 		break;
44 	case NbDgramError:
45 		if (p + 1 > ep)
46 			return 0;
47 		s->error.code = *p++;
48 		break;
49 	case NbDgramQueryRequest:
50 	case NbDgramPositiveQueryResponse:
51 	case NbDgramNegativeQueryResponse:
52 		n = nbnamedecode(p, p, ep, s->query.dstname);
53 		if (n == 0)
54 			return 0;
55 		p += n;
56 		break;
57 	default:
58 		return 0;
59 	}
60 	return p - ap;
61 }
62 
63 int
nbdgramconvS2M(uchar * ap,uchar * ep,NbDgram * s)64 nbdgramconvS2M(uchar *ap, uchar *ep, NbDgram *s)
65 {
66 	uchar *p = ap;
67 	uchar *fixup;
68 	int n;
69 
70 	if (p + 6 + IPv4addrlen > ep)
71 		return 0;
72 	*p++ = s->type;
73 	*p++ = s->flags;
74 	hnputs(p, s->id); p+= 2;
75 	v6tov4(p, s->srcip); p += IPv4addrlen;
76 	hnputs(p, s->srcport); p+= 2;
77 	switch (s->type) {
78 	case NbDgramDirectUnique:
79 	case NbDgramDirectGroup:
80 	case NbDgramBroadcast:
81 		if (p + 4 > ep)
82 			return 0;
83 		fixup = p;
84 		hnputs(p, s->datagram.length); p += 2;
85 		hnputs(p, s->datagram.offset); p += 2;
86 		n = nbnameencode(p, ep, s->datagram.srcname);
87 		if (n == 0)
88 			return 0;
89 		p += n;
90 		n = nbnameencode(p, ep, s->datagram.dstname);
91 		if (n == 0)
92 			return 0;
93 		p += n;
94 		if (p + s->datagram.length > ep)
95 			return 0;
96 		memcpy(p, s->datagram.data, s->datagram.length); p += s->datagram.length;
97 		hnputs(fixup, p - fixup - 4);
98 		break;
99 	case NbDgramError:
100 		if (p + 1 > ep)
101 			return 0;
102 		*p++ = s->error.code;
103 		break;
104 	case NbDgramQueryRequest:
105 	case NbDgramPositiveQueryResponse:
106 	case NbDgramNegativeQueryResponse:
107 		n = nbnameencode(p, ep, s->datagram.dstname);
108 		if (n == 0)
109 			return 0;
110 		p += n;
111 		break;
112 	default:
113 		return 0;
114 	}
115 	return p - ap;
116 }
117