nbnsconv.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <ip.h>
  12. #include <thread.h>
  13. #include "netbios.h"
  14. void
  15. nbnsmessagequestionfree(NbnsMessageQuestion **qp)
  16. {
  17. NbnsMessageQuestion *q = *qp;
  18. if (q) {
  19. free(q);
  20. *qp = nil;
  21. }
  22. }
  23. void
  24. nbnsmessageresourcefree(NbnsMessageResource **rp)
  25. {
  26. NbnsMessageResource *r = *rp;
  27. if (r) {
  28. free(r->rdata);
  29. free(r);
  30. *rp = nil;
  31. }
  32. }
  33. static void
  34. questionfree(NbnsMessageQuestion **qp)
  35. {
  36. while (*qp) {
  37. NbnsMessageQuestion *next = (*qp)->next;
  38. nbnsmessagequestionfree(qp);
  39. *qp = next;
  40. }
  41. }
  42. static void
  43. resourcefree(NbnsMessageResource **rp)
  44. {
  45. while (*rp) {
  46. NbnsMessageResource *next = (*rp)->next;
  47. nbnsmessageresourcefree(rp);
  48. *rp = next;
  49. }
  50. }
  51. void
  52. nbnsmessagefree(NbnsMessage **sp)
  53. {
  54. NbnsMessage *s = *sp;
  55. if (s) {
  56. questionfree(&s->q);
  57. resourcefree(&s->an);
  58. resourcefree(&s->ns);
  59. resourcefree(&s->ar);
  60. free(s);
  61. *sp = nil;
  62. }
  63. }
  64. void
  65. nbnsmessageaddquestion(NbnsMessage *s, NbnsMessageQuestion *q)
  66. {
  67. NbnsMessageQuestion **qp;
  68. for (qp = &s->q; *qp; qp = &(*qp)->next)
  69. ;
  70. *qp = q;
  71. }
  72. NbnsMessageQuestion *
  73. nbnsmessagequestionnew(NbName name, uint16_t type, uint16_t class)
  74. {
  75. NbnsMessageQuestion *q;
  76. q = mallocz(sizeof(*q), 1);
  77. if (q == nil)
  78. return nil;
  79. nbnamecpy(q->name, name);
  80. q->type = type;
  81. q->class = class;
  82. return q;
  83. }
  84. NbnsMessageResource *
  85. nbnsmessageresourcenew(NbName name, uint16_t type, uint16_t class,
  86. uint32_t ttl,
  87. int rdlength, uint8_t *rdata)
  88. {
  89. NbnsMessageResource *r;
  90. r= mallocz(sizeof(*r), 1);
  91. if (r == nil)
  92. return nil;
  93. nbnamecpy(r->name, name);
  94. r->type = type;
  95. r->class = class;
  96. r->ttl = ttl;
  97. r->rdlength = rdlength;
  98. if (rdlength) {
  99. r->rdata = malloc(rdlength);
  100. if (r->rdata == nil) {
  101. free(r);
  102. return nil;
  103. }
  104. memcpy(r->rdata, rdata, rdlength);
  105. }
  106. return r;
  107. }
  108. void
  109. nbnsmessageaddresource(NbnsMessageResource **rp, NbnsMessageResource *r)
  110. {
  111. for (; *rp; rp = &(*rp)->next)
  112. ;
  113. *rp = r;
  114. }
  115. NbnsMessage *
  116. nbnsmessagenew(void)
  117. {
  118. return mallocz(sizeof(NbnsMessage), 1);
  119. }
  120. static int
  121. resourcedecode(NbnsMessageResource **headp, int count, uint8_t *ap,
  122. uint8_t *pp, uint8_t *ep)
  123. {
  124. uint8_t *p = pp;
  125. int i;
  126. for (i = 0; i < count; i++) {
  127. int n;
  128. NbnsMessageResource *r, **rp;
  129. r = mallocz(sizeof(NbnsMessageResource), 1);
  130. if (r == nil)
  131. return -1;
  132. for (rp = headp; *rp; rp = &(*rp)->next)
  133. ;
  134. *rp = r;
  135. n = nbnamedecode(ap, p, ep, r->name);
  136. if (n == 0)
  137. return -1;
  138. p += n;
  139. if (p + 10 > ep)
  140. return -1;
  141. r->type = nhgets(p); p += 2;
  142. r->class = nhgets(p); p += 2;
  143. r->ttl = nhgetl(p); p += 4;
  144. r->rdlength = nhgets(p); p += 2;
  145. //print("rdlength %d\n", r->rdlength);
  146. if (r->rdlength) {
  147. if (p + r->rdlength > ep)
  148. return -1;
  149. r->rdata = malloc(r->rdlength);
  150. if (r == nil)
  151. return -1;
  152. memcpy(r->rdata, p, r->rdlength);
  153. p += r->rdlength;
  154. }
  155. }
  156. return p - pp;
  157. }
  158. NbnsMessage *
  159. nbnsconvM2S(uint8_t *ap, int nap)
  160. {
  161. uint8_t *p, *ep;
  162. uint16_t qdcount, ancount, nscount, arcount, ctrl;
  163. int i;
  164. NbnsMessage *s;
  165. int n;
  166. if (nap < 12)
  167. return nil;
  168. p = ap;
  169. ep = ap + nap;
  170. s = nbnsmessagenew();
  171. if (s == nil)
  172. return nil;
  173. s->id = nhgets(p); p+= 2;
  174. ctrl = nhgets(p); p += 2;
  175. qdcount = nhgets(p); p += 2;
  176. ancount = nhgets(p); p += 2;
  177. nscount = nhgets(p); p += 2;
  178. arcount = nhgets(p); p += 2;
  179. s->response = (ctrl & NbnsResponse) != 0;
  180. s->opcode = (ctrl >> NbnsOpShift) & NbnsOpMask;
  181. s->broadcast = (ctrl & NbnsFlagBroadcast) != 0;
  182. s->recursionavailable = (ctrl & NbnsFlagRecursionAvailable) != 0;
  183. s->recursiondesired = (ctrl & NbnsFlagRecursionDesired) != 0;
  184. s->truncation = (ctrl & NbnsFlagTruncation) != 0;
  185. s->authoritativeanswer = (ctrl & NbnsFlagAuthoritativeAnswer) != 0;
  186. s->rcode = s->response ? (ctrl & NbnsRcodeMask) : 0;
  187. for (i = 0; i < qdcount; i++) {
  188. int n;
  189. NbName nbname;
  190. NbnsMessageQuestion *q;
  191. uint16_t type, class;
  192. n = nbnamedecode(ap, p, ep, nbname);
  193. if (n == 0)
  194. goto fail;
  195. p += n;
  196. if (p + 4 > ep)
  197. goto fail;
  198. type = nhgets(p); p += 2;
  199. class = nhgets(p); p += 2;
  200. q = nbnsmessagequestionnew(nbname, type, class);
  201. if (q == nil)
  202. goto fail;
  203. nbnsmessageaddquestion(s, q);
  204. }
  205. n = resourcedecode(&s->an, ancount, ap, p, ep);
  206. if (n < 0)
  207. goto fail;
  208. p += n;
  209. n = resourcedecode(&s->ns, nscount, ap, p, ep);
  210. if (n < 0)
  211. goto fail;
  212. p += n;
  213. n = resourcedecode(&s->ar, arcount, ap, p, ep);
  214. if (n < 0)
  215. goto fail;
  216. //print("arcount %d\n", arcount);
  217. return s;
  218. fail:
  219. nbnsmessagefree(&s);
  220. return nil;
  221. }
  222. static int
  223. resourceencode(NbnsMessageResource *r, uint8_t *ap, uint8_t *ep)
  224. {
  225. uint8_t *p = ap;
  226. for (; r; r = r->next) {
  227. int n = nbnameencode(p, ep, r->name);
  228. if (n == 0)
  229. return -1;
  230. p += n;
  231. if (p + 10 > ep)
  232. return -1;
  233. hnputs(p, r->type); p += 2;
  234. hnputs(p, r->class); p += 2;
  235. hnputl(p, r->ttl); p += 4;
  236. hnputs(p, r->rdlength); p += 2;
  237. if (p + r->rdlength > ep)
  238. return -1;
  239. memcpy(p, r->rdata, r->rdlength);
  240. p += r->rdlength;
  241. }
  242. return p - ap;
  243. }
  244. int
  245. nbnsconvS2M(NbnsMessage *s, uint8_t *ap, int nap)
  246. {
  247. uint8_t *p = ap;
  248. uint8_t *ep = ap + nap;
  249. uint16_t ctrl;
  250. NbnsMessageQuestion *q;
  251. NbnsMessageResource *r;
  252. int k;
  253. int n;
  254. if (p + 12 > ep)
  255. return 0;
  256. hnputs(p, s->id); p+= 2;
  257. ctrl = (s->opcode & NbnsOpMask) << NbnsOpShift;
  258. if (s->response) {
  259. ctrl |= s->rcode & NbnsRcodeMask;
  260. ctrl |= NbnsResponse;
  261. }
  262. if (s->broadcast)
  263. ctrl |= NbnsFlagBroadcast;
  264. if (s->recursionavailable)
  265. ctrl |= NbnsFlagRecursionAvailable;
  266. if (s->recursiondesired)
  267. ctrl |= NbnsFlagRecursionDesired;
  268. if (s->truncation)
  269. ctrl |= NbnsFlagTruncation;
  270. if (s->authoritativeanswer)
  271. ctrl |= NbnsFlagAuthoritativeAnswer;
  272. hnputs(p, ctrl); p += 2;
  273. for (q = s->q, k = 0; q; k++, q = q->next)
  274. ;
  275. hnputs(p, k); p += 2;
  276. for (r = s->an, k = 0; r; k++, r = r->next)
  277. ;
  278. hnputs(p, k); p += 2;
  279. for (r = s->ns, k = 0; r; k++, r = r->next)
  280. ;
  281. hnputs(p, k); p += 2;
  282. for (r = s->ar, k = 0; r; k++, r = r->next)
  283. ;
  284. hnputs(p, k); p += 2;
  285. for (q = s->q; q; q = q->next) {
  286. int n = nbnameencode(p, ep, q->name);
  287. if (n == 0)
  288. return 0;
  289. p += n;
  290. if (p + 4 > ep)
  291. return 0;
  292. hnputs(p, q->type); p += 2;
  293. hnputs(p, q->class); p += 2;
  294. }
  295. n = resourceencode(s->an, p, ep);
  296. if (n < 0)
  297. return 0;
  298. p += n;
  299. n = resourceencode(s->ns, p, ep);
  300. if (n < 0)
  301. return 0;
  302. p += n;
  303. n = resourceencode(s->ar, p, ep);
  304. if (n < 0)
  305. return 0;
  306. p += n;
  307. return p - ap;
  308. }