raw_usrreq.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /* $OpenBSD: raw_usrreq.c,v 1.21 2015/07/15 22:16:42 deraadt Exp $ */
  2. /* $NetBSD: raw_usrreq.c,v 1.11 1996/02/13 22:00:43 christos Exp $ */
  3. /*
  4. * Copyright (c) 1980, 1986, 1993
  5. * The Regents of the University of California. All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the University nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93
  32. */
  33. #include <sys/param.h>
  34. #include <sys/mbuf.h>
  35. #include <sys/domain.h>
  36. #include <sys/protosw.h>
  37. #include <sys/socket.h>
  38. #include <sys/socketvar.h>
  39. #include <sys/errno.h>
  40. #include <sys/systm.h>
  41. #include <net/netisr.h>
  42. #include <net/raw_cb.h>
  43. #include <sys/stdarg.h>
  44. /*
  45. * Initialize raw connection block q.
  46. */
  47. void
  48. raw_init(void)
  49. {
  50. LIST_INIT(&rawcb);
  51. }
  52. /*
  53. * Raw protocol input routine. Find the socket
  54. * associated with the packet(s) and move them over. If
  55. * nothing exists for this packet, drop it.
  56. */
  57. /*
  58. * Raw protocol interface.
  59. */
  60. void
  61. raw_input(struct mbuf *m0, ...)
  62. {
  63. struct rawcb *rp;
  64. struct mbuf *m = m0;
  65. int sockets = 0;
  66. struct socket *last;
  67. va_list ap;
  68. struct sockproto *proto;
  69. struct sockaddr *src, *dst;
  70. va_start(ap, m0);
  71. proto = va_arg(ap, struct sockproto *);
  72. src = va_arg(ap, struct sockaddr *);
  73. dst = va_arg(ap, struct sockaddr *);
  74. va_end(ap);
  75. last = 0;
  76. LIST_FOREACH(rp, &rawcb, rcb_list) {
  77. if (rp->rcb_socket->so_state & SS_CANTRCVMORE)
  78. continue;
  79. if (rp->rcb_proto.sp_family != proto->sp_family)
  80. continue;
  81. if (rp->rcb_proto.sp_protocol &&
  82. rp->rcb_proto.sp_protocol != proto->sp_protocol)
  83. continue;
  84. /*
  85. * We assume the lower level routines have
  86. * placed the address in a canonical format
  87. * suitable for a structure comparison.
  88. *
  89. * Note that if the lengths are not the same
  90. * the comparison will fail at the first byte.
  91. */
  92. #define equal(a1, a2) \
  93. (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
  94. if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
  95. continue;
  96. if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
  97. continue;
  98. if (last) {
  99. struct mbuf *n;
  100. if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) != NULL) {
  101. if (sbappendaddr(&last->so_rcv, src,
  102. n, (struct mbuf *)NULL) == 0)
  103. /* should notify about lost packet */
  104. m_freem(n);
  105. else {
  106. sorwakeup(last);
  107. sockets++;
  108. }
  109. }
  110. }
  111. last = rp->rcb_socket;
  112. }
  113. if (last) {
  114. if (sbappendaddr(&last->so_rcv, src,
  115. m, (struct mbuf *)NULL) == 0)
  116. m_freem(m);
  117. else {
  118. sorwakeup(last);
  119. sockets++;
  120. }
  121. } else
  122. m_freem(m);
  123. }
  124. /*ARGSUSED*/
  125. void *
  126. raw_ctlinput(int cmd, struct sockaddr *arg, u_int rdomain, void *d)
  127. {
  128. if (cmd < 0 || cmd >= PRC_NCMDS)
  129. return NULL;
  130. return NULL;
  131. /* INCOMPLETE */
  132. }
  133. /*ARGSUSED*/
  134. int
  135. raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
  136. struct mbuf *control, struct proc *p)
  137. {
  138. struct rawcb *rp = sotorawcb(so);
  139. int error = 0;
  140. int len, s;
  141. if (req == PRU_CONTROL)
  142. return (EOPNOTSUPP);
  143. if (control && control->m_len) {
  144. error = EOPNOTSUPP;
  145. goto release;
  146. }
  147. if (rp == 0) {
  148. error = EINVAL;
  149. goto release;
  150. }
  151. s = splsoftnet();
  152. switch (req) {
  153. /*
  154. * Allocate a raw control block and fill in the
  155. * necessary info to allow packets to be routed to
  156. * the appropriate raw interface routine.
  157. */
  158. case PRU_ATTACH:
  159. if ((so->so_state & SS_PRIV) == 0) {
  160. error = EACCES;
  161. break;
  162. }
  163. error = raw_attach(so, (int)(long)nam);
  164. break;
  165. /*
  166. * Destroy state just before socket deallocation.
  167. * Flush data or not depending on the options.
  168. */
  169. case PRU_DETACH:
  170. if (rp == 0) {
  171. error = ENOTCONN;
  172. break;
  173. }
  174. raw_detach(rp);
  175. break;
  176. #ifdef notdef
  177. /*
  178. * If a socket isn't bound to a single address,
  179. * the raw input routine will hand it anything
  180. * within that protocol family (assuming there's
  181. * nothing else around it should go to).
  182. */
  183. case PRU_CONNECT:
  184. if (rp->rcb_faddr) {
  185. error = EISCONN;
  186. break;
  187. }
  188. nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
  189. rp->rcb_faddr = mtod(nam, struct sockaddr *);
  190. soisconnected(so);
  191. break;
  192. case PRU_BIND:
  193. if (rp->rcb_laddr) {
  194. error = EINVAL; /* XXX */
  195. break;
  196. }
  197. error = raw_bind(so, nam);
  198. break;
  199. #else
  200. case PRU_CONNECT:
  201. case PRU_BIND:
  202. #endif
  203. case PRU_CONNECT2:
  204. error = EOPNOTSUPP;
  205. break;
  206. case PRU_DISCONNECT:
  207. if (rp->rcb_faddr == 0) {
  208. error = ENOTCONN;
  209. break;
  210. }
  211. raw_disconnect(rp);
  212. soisdisconnected(so);
  213. break;
  214. /*
  215. * Mark the connection as being incapable of further input.
  216. */
  217. case PRU_SHUTDOWN:
  218. socantsendmore(so);
  219. break;
  220. /*
  221. * Ship a packet out. The appropriate raw output
  222. * routine handles any massaging necessary.
  223. */
  224. case PRU_SEND:
  225. if (nam) {
  226. if (rp->rcb_faddr) {
  227. error = EISCONN;
  228. break;
  229. }
  230. rp->rcb_faddr = mtod(nam, struct sockaddr *);
  231. } else if (rp->rcb_faddr == 0) {
  232. error = ENOTCONN;
  233. break;
  234. }
  235. error = (*so->so_proto->pr_output)(m, so);
  236. m = NULL;
  237. if (nam)
  238. rp->rcb_faddr = 0;
  239. break;
  240. case PRU_ABORT:
  241. raw_disconnect(rp);
  242. sofree(so);
  243. soisdisconnected(so);
  244. break;
  245. case PRU_SENSE:
  246. /*
  247. * stat: don't bother with a blocksize.
  248. */
  249. splx(s);
  250. return (0);
  251. /*
  252. * Not supported.
  253. */
  254. case PRU_RCVOOB:
  255. case PRU_RCVD:
  256. splx(s);
  257. return (EOPNOTSUPP);
  258. case PRU_LISTEN:
  259. case PRU_ACCEPT:
  260. case PRU_SENDOOB:
  261. error = EOPNOTSUPP;
  262. break;
  263. case PRU_SOCKADDR:
  264. if (rp->rcb_laddr == 0) {
  265. error = EINVAL;
  266. break;
  267. }
  268. len = rp->rcb_laddr->sa_len;
  269. bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
  270. nam->m_len = len;
  271. break;
  272. case PRU_PEERADDR:
  273. if (rp->rcb_faddr == 0) {
  274. error = ENOTCONN;
  275. break;
  276. }
  277. len = rp->rcb_faddr->sa_len;
  278. bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
  279. nam->m_len = len;
  280. break;
  281. default:
  282. panic("raw_usrreq");
  283. }
  284. splx(s);
  285. release:
  286. m_freem(m);
  287. return (error);
  288. }