PageRenderTime 41ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/cpukit/libnetworking/net/raw_usrreq.c

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