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