findname.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <ip.h>
  4. #include <thread.h>
  5. #include "netbios.h"
  6. int
  7. nbnsfindname(uchar *serveripaddr, NbName name, uchar *ipaddr, ulong *ttlp)
  8. {
  9. NbnsMessage *nq;
  10. Alt aa[3];
  11. int tries = NbnsRetryBroadcast;
  12. NbnsAlarm *a;
  13. int rv;
  14. NbnsMessage *response;
  15. nq = nbnsmessagenamequeryrequestnew(0, serveripaddr == nil, name);
  16. if (nq == nil)
  17. return -1;
  18. a = nbnsalarmnew();
  19. if (a == nil) {
  20. free(nq);
  21. return -1;
  22. }
  23. aa[0].c = a->c;
  24. aa[0].v = nil;
  25. aa[0].op = CHANRCV;
  26. aa[1].op = CHANRCV;
  27. aa[2].op = CHANEND;
  28. while (tries > 0) {
  29. NbnsTransaction *t;
  30. nq->id = nbnsnextid();
  31. t = nbnstransactionnew(nq, serveripaddr);
  32. aa[1].c = t->c;
  33. aa[1].v = &response;
  34. nbnsalarmset(a, NbnsTimeoutBroadcast);
  35. for (;;) {
  36. int i;
  37. i = alt(aa);
  38. if (i == 0) {
  39. tries--;
  40. break;
  41. }
  42. else if (i == 1) {
  43. if (response->opcode == NbnsOpQuery) {
  44. nbnstransactionfree(&t);
  45. goto done;
  46. }
  47. nbnsmessagefree(&response);
  48. }
  49. }
  50. nbnstransactionfree(&t);
  51. }
  52. done:
  53. if (tries == 0)
  54. rv = -1;
  55. else {
  56. if (response->rcode != 0)
  57. rv = response->rcode;
  58. else if (response->an == nil)
  59. rv = -1;
  60. else {
  61. rv = 0;
  62. v4tov6(ipaddr, response->an->rdata + 2);
  63. if (ttlp)
  64. *ttlp = response->an->ttl;
  65. }
  66. nbnsmessagefree(&response);
  67. }
  68. nbnsalarmfree(&a);
  69. nbnsmessagefree(&nq);
  70. return rv;
  71. }