net_stream.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/fcntl.h>
  4. #include <sys/errno.h>
  5. #include <sys/stream.h>
  6. #include <sys/stropts.h>
  7. #include <sys/tihdr.h>
  8. extern int errno;
  9. int
  10. net_open (char *path, int oflags, void *addr, int addrlen)
  11. {
  12. int fd;
  13. int flags;
  14. if ((fd = open (path, oflags)) < 0)
  15. {
  16. perror ("open");
  17. return (-1);
  18. }
  19. return (fd);
  20. }
  21. int
  22. net_bind (int fd, void *addr, int addrlen)
  23. {
  24. struct {
  25. struct T_bind_req msg_hdr;
  26. char addr[128];
  27. } bind_req;
  28. struct strbuf ctlbuf;
  29. union T_primitives rcvbuf;
  30. struct T_error_ack *error_ack;
  31. int flags;
  32. if (addr == NULL || addrlen == 0)
  33. {
  34. fprintf (stderr, "No address\n");
  35. return (-1);
  36. }
  37. bind_req.msg_hdr.PRIM_type = T_BIND_REQ;
  38. bind_req.msg_hdr.ADDR_length = addrlen;
  39. bind_req.msg_hdr.ADDR_offset = sizeof (struct T_bind_req);
  40. bind_req.msg_hdr.CONIND_number = 5;
  41. bcopy (addr, bind_req.addr, addrlen);
  42. ctlbuf.len = sizeof (struct T_bind_req) + addrlen;
  43. ctlbuf.buf = (char *) &bind_req;
  44. if (putmsg (fd, &ctlbuf, NULL, 0) < 0)
  45. {
  46. return (-1);
  47. }
  48. /*
  49. * Wait for acknowledgement
  50. */
  51. ctlbuf.maxlen = sizeof (union T_primitives);
  52. ctlbuf.len = 0;
  53. ctlbuf.buf = (char *) &rcvbuf;
  54. flags = RS_HIPRI;
  55. if (getmsg (fd, &ctlbuf, NULL, &flags) < 0)
  56. {
  57. perror ("getmsg");
  58. return (-1);
  59. }
  60. if (ctlbuf.len < sizeof (long))
  61. {
  62. fprintf (stderr, "Bad length from getmsg.\n");
  63. errno = EPROTO;
  64. return (-1);
  65. }
  66. switch (rcvbuf.type)
  67. {
  68. case T_BIND_ACK:
  69. return (fd);
  70. case T_ERROR_ACK:
  71. if (ctlbuf.len < sizeof (struct T_error_ack))
  72. {
  73. errno = EPROTO;
  74. return (-1);
  75. }
  76. error_ack = (struct T_error_ack *) &rcvbuf;
  77. fprintf (stderr, "Error ack from bind (%d %d %d)\n",
  78. error_ack->ERROR_prim,
  79. error_ack->TLI_error,
  80. error_ack->UNIX_error);
  81. errno = error_ack->UNIX_error;
  82. break;
  83. default:
  84. fprintf (stderr, "No ack from bind?\n");
  85. errno = EPROTO;
  86. break;
  87. }
  88. return (-1);
  89. }
  90. int
  91. net_send (int fd, char *buf, int len, char *to_addr, int addrlen)
  92. {
  93. struct strbuf ctlbuf;
  94. struct strbuf databuf;
  95. struct {
  96. struct T_unitdata_req unitdata_req;
  97. char buf[128];
  98. } netdata;
  99. bcopy (to_addr, netdata.buf, addrlen);
  100. netdata.unitdata_req.PRIM_type = T_UNITDATA_REQ;
  101. netdata.unitdata_req.DEST_length = addrlen;
  102. netdata.unitdata_req.DEST_offset = sizeof (struct T_unitdata_req);
  103. /*
  104. * for now, presume no options.
  105. */
  106. netdata.unitdata_req.OPT_length = 0;
  107. netdata.unitdata_req.OPT_offset = 0;
  108. ctlbuf.len = sizeof (struct T_unitdata_req) + addrlen;
  109. ctlbuf.buf = (char *) &netdata;
  110. databuf.len = len;
  111. databuf.buf = buf;
  112. if (putmsg (fd, &ctlbuf, &databuf, 0) < 0)
  113. return (0);
  114. free (netdata.buf);
  115. return (len);
  116. }
  117. int
  118. net_recv (int fd, char *buf, int len, char *from_addr, int addrlen)
  119. {
  120. struct strbuf ctlbuf;
  121. struct strbuf databuf;
  122. struct {
  123. struct T_unitdata_ind unitdata_ind;
  124. char buf[128];
  125. } netdata;
  126. char *c;
  127. int retval;
  128. int flags;
  129. ctlbuf.maxlen = sizeof (netdata);
  130. ctlbuf.buf = (char *) &netdata;
  131. databuf.maxlen = len;
  132. databuf.len = 0;
  133. databuf.buf = buf;
  134. flags = 0;
  135. if ((retval = getmsg (fd, &ctlbuf, &databuf, &flags)) < 0)
  136. return (-1);
  137. if (netdata.unitdata_ind.PRIM_type != T_UNITDATA_IND)
  138. {
  139. fprintf (stderr, "net_recv: Got %d\n", netdata.unitdata_ind.PRIM_type);
  140. errno = EPROTO;
  141. return (0);
  142. }
  143. if (retval)
  144. {
  145. errno = EIO;
  146. return (0);
  147. }
  148. /*
  149. * Copy return address for the user
  150. */
  151. if (netdata.unitdata_ind.SRC_length < addrlen)
  152. addrlen = netdata.unitdata_ind.SRC_length;
  153. c = (char *) &netdata;
  154. bcopy (&(c[netdata.unitdata_ind.SRC_offset]),
  155. from_addr,
  156. addrlen);
  157. return (databuf.len);
  158. }