raw_ip.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:18k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* raw_ip.c - raw interface to IP protocol */
  2. /* Copyright 1984 - 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright (c) 1982, 1986, 1988, 1993, 1995
  6.  * The Regents of the University of California.  All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  * This product includes software developed by the University of
  19.  * California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  *
  36.  * @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
  37.  */
  38. /*
  39. modification history
  40. --------------------
  41. 01j,20may02,vvv  fixed rip_input to send ICMP protocol unreachable errors 
  42.  only when called directly from ip_input (SPR #75405)
  43. 01i,21mar02,rae  Allow ICMP to be excluded (SPR #73703)
  44. 01h,12oct01,rae  merge from truestack ver 01o, base 01g (SPRs 69657,
  45.                  35258, etc)
  46. 01g,26aug98,n_s  corrected rip_output for IP_HDRINCL case. spr #22246
  47. 01f,26aug98,n_s  added return val check for M_PREPEND in rip_output and
  48.                  mBufClGet in rip_ctloutput. spr # 22238.
  49. 01e,16apr97,vin  added PRU_CONTROL support to rip_usrreq().
  50. 01d,08apr97,vin  include pcb hashing changes from FREEBSD2.2.1, removed
  51.  ip_mrouter, added mCastRouteCmdHook. removed all MROUTING
  52. 01c,31jan97,vin  changed declaration according to prototype decl in protosw.h
  53. 01b,22nov96,vin  added cluster support replaced m_get(..) with mBufClGet(..).
  54. 01a,03mar96,vin  created from BSD4.4 stuff,integrated with 02i of raw_usrreq.c
  55. */
  56. /*
  57. DESCRIPTION
  58. */
  59. #include "vxWorks.h"
  60. #include "net/mbuf.h"
  61. #include "sys/socket.h"
  62. #include "net/protosw.h"
  63. #include "net/socketvar.h"
  64. #include "errno.h"
  65. #include "net/if.h"
  66. #include "net/route.h"
  67. #include "net/raw_cb.h"
  68. #include "netinet/in.h"
  69. #include "netinet/in_systm.h"
  70. #include "netinet/in_var.h"
  71. #include "netinet/ip.h"
  72. #include "netinet/ip_icmp.h"
  73. #include "netinet/ip_var.h"
  74. #include "netinet/ip_mroute.h"
  75. #include "netinet/in_pcb.h"
  76. #ifdef WV_INSTRUMENTATION
  77. #ifdef INCLUDE_WVNET
  78. #include "wvNetLib.h"
  79. #endif
  80. #endif
  81. /* externs */
  82. extern FUNCPTR _mCastRouteCmdHook; /* WRS mcast route command hook */
  83. extern VOIDFUNCPTR _icmpErrorHook;
  84. extern int icmp_ctloutput (int, struct socket *, int, int, struct mbuf **);
  85. extern struct protosw inetsw[];
  86. extern u_char ip_protox[IPPROTO_MAX];
  87. /* globals */
  88. #ifndef VIRTUAL_STACK
  89. static struct inpcbhead ripcb;
  90. static struct inpcbinfo ripcbinfo;
  91. static struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
  92. #endif /* VIRTUAL_STACK */
  93. #ifdef VIRTUAL_STACK
  94. #include "netinet/vsLib.h"
  95. #endif
  96. /*
  97.  * Nominal space allocated to a raw ip socket.
  98.  */
  99. #define RIPSNDQ 8192
  100. #define RIPRCVQ 8192
  101. /* locals */
  102. static int _mCastCtlOutput (int option, int optName, struct socket * sockPtr,
  103.                             struct mbuf ** pPtrMbuf); 
  104. #ifdef WV_INSTRUMENTATION
  105. #ifdef INCLUDE_WVNET
  106.     /* Set common fields of event identifiers for this module. */
  107. LOCAL UCHAR wvNetModuleId = WV_NET_RAWIP_MODULE;   /* Value for raw_ip.c */
  108. LOCAL UCHAR wvNetLocalFilter = WV_NET_NONE;     /* Available event filter */
  109. LOCAL ULONG wvNetEventId;       /* Event identifier: see wvNetLib.h */
  110. #endif    /* INCLUDE_WVNET */
  111. #endif
  112. /*
  113.  * Raw interface to IP protocol.
  114.  */
  115. /*
  116.  * Initialize raw connection block q.
  117.  */
  118. void
  119. rip_init()
  120. {
  121. #ifdef WV_INSTRUMENTATION
  122. #ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */
  123.     WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_VERBOSE, 31, 11,
  124.                      WV_NETEVENT_RAWIPINIT_START)
  125. #endif  /* INCLUDE_WVNET */
  126. #endif
  127. LIST_INIT(&ripcb);
  128.         ripcbinfo.listhead = &ripcb;
  129.         /*
  130.          * XXX We don't use the hash list for raw IP, but it's easier
  131.          * to allocate a one entry hash list than it is to check all
  132.          * over the place for hashbase == NULL.
  133.          */
  134.         ripcbinfo.hashbase = hashinit(1, MT_PCB, &ripcbinfo.hashmask);
  135. #ifdef VIRTUAL_STACK
  136.         rip_sendspace = RIPSNDQ;
  137.         rip_recvspace = RIPRCVQ;
  138.         ripsrc.sin_len = sizeof(struct sockaddr_in);
  139.         ripsrc.sin_family = AF_INET;
  140. #endif /* VIRTUAL_STACK */
  141. }
  142. /*
  143.  * Setup generic address and protocol structures
  144.  * for raw_input routine, then pass them along with
  145.  * mbuf chain.
  146.  */
  147. void
  148. rip_input(m)
  149. struct mbuf *m;
  150. {
  151. register struct ip *ip = mtod(m, struct ip *);
  152. register struct inpcb *inp;
  153. struct socket *last = 0;
  154. #ifdef WV_INSTRUMENTATION
  155. #ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */
  156.     WV_NET_EVENT_0 (NET_CORE_EVENT, WV_NET_NOTICE, 14, 7,
  157.                      WV_NETEVENT_RAWIPIN_START, WV_NET_RECV)
  158. #endif  /* INCLUDE_WVNET */
  159. #endif
  160. ripsrc.sin_addr = ip->ip_src;
  161.         * (int *)ripsrc.sin_zero = m->m_pkthdr.rcvif->if_index;
  162.         for (inp = ripcb.lh_first; inp != NULL; inp = inp->inp_list.le_next) {
  163. if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p)
  164. continue;
  165. if (inp->inp_laddr.s_addr &&
  166.     inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
  167. continue;
  168. if (inp->inp_faddr.s_addr &&
  169.     inp->inp_faddr.s_addr != ip->ip_src.s_addr)
  170. continue;
  171. if (last) {
  172. struct mbuf *n;
  173. if ((n = m_copy(m, 0, (int)M_COPYALL))) {
  174. if (sbappendaddr(&last->so_rcv,
  175.     (struct sockaddr *)&ripsrc, n,
  176.     (struct mbuf *)0) == 0)
  177.                                     {
  178. #ifdef WV_INSTRUMENTATION
  179. #ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */
  180.                 WV_NET_ADDRIN_EVENT_3 (NET_CORE_EVENT, WV_NET_WARNING, 9, 6,
  181.                                        ip->ip_src.s_addr, ip->ip_dst.s_addr,
  182.                                        WV_NETEVENT_RAWIPIN_LOST, WV_NET_RECV,
  183.                                        last->so_fd, ip->ip_src.s_addr,
  184.                                        ip->ip_dst.s_addr)
  185. #endif  /* INCLUDE_WVNET */
  186. #endif
  187. /* should notify about lost packet */
  188. m_freem(n);
  189.                                     }
  190. else
  191. sorwakeup(last);
  192. }
  193. }
  194. last = inp->inp_socket;
  195. }
  196. if (last) {
  197. if (sbappendaddr(&last->so_rcv, (struct sockaddr *)&ripsrc,
  198.     m, (struct mbuf *)0) == 0)
  199.                     {
  200. #ifdef WV_INSTRUMENTATION
  201. #ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */
  202.                 WV_NET_ADDRIN_EVENT_3 (NET_CORE_EVENT, WV_NET_WARNING, 9, 6,
  203.                                        ip->ip_src.s_addr, ip->ip_dst.s_addr,
  204.                                        WV_NETEVENT_RAWIPIN_LOST, WV_NET_RECV,
  205.                                        last->so_fd, ip->ip_src.s_addr,
  206.                                        ip->ip_dst.s_addr)
  207. #endif  /* INCLUDE_WVNET */
  208. #endif
  209. m_freem(m);
  210.                     }
  211. else
  212. sorwakeup(last);
  213. } else {
  214. #ifdef WV_INSTRUMENTATION
  215. #ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */
  216.             WV_NET_ADDRIN_EVENT_2 (NET_CORE_EVENT, WV_NET_ERROR, 35, 5,
  217.                                    ip->ip_src.s_addr, ip->ip_dst.s_addr,
  218.                                    WV_NETEVENT_RAWIPIN_NOSOCK, WV_NET_RECV,
  219.                                    ip->ip_src.s_addr, ip->ip_dst.s_addr)
  220. #endif  /* INCLUDE_WVNET */
  221. #endif
  222.                 if ((_icmpErrorHook) && 
  223.     (inetsw[ip_protox[ip->ip_p]].pr_protocol == IPPROTO_RAW))
  224.                     _icmpErrorHook (m, ICMP_UNREACH, ICMP_UNREACH_PROTOCOL, 
  225.                                     ip->ip_src.s_addr, 0);
  226. m_freem(m);
  227. #ifdef VIRTUAL_STACK
  228. _ipstat.ips_noproto++;
  229. _ipstat.ips_delivered--;
  230. #else
  231. ipstat.ips_noproto++;
  232. ipstat.ips_delivered--;
  233. #endif /* VIRTUAL_STACK */
  234. }
  235. return;
  236. }
  237. /*
  238.  * Generate IP header and pass packet to ip_output.
  239.  * Tack on options user may have setup with control call.
  240.  */
  241. int
  242. rip_output(m, so, dst)
  243. register struct mbuf *m;
  244. struct socket *so;
  245. u_long dst;
  246. {
  247. register struct ip *ip;
  248. register struct inpcb *inp = sotoinpcb(so);
  249. struct mbuf *opts;
  250. int flags = (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST;
  251.         int result;
  252. /*
  253.  * If the user handed us a complete IP packet, use it.
  254.  * Otherwise, allocate an mbuf for a header and fill it in.
  255.  */
  256. if ((inp->inp_flags & INP_HDRINCL) == 0) {
  257. M_PREPEND(m, sizeof(struct ip), M_WAIT);
  258. if (m == (struct mbuf *) NULL)
  259.     {
  260.     return (ENOBUFS);
  261.     }
  262.     
  263. ip = mtod(m, struct ip *);
  264. ip->ip_tos = 0;
  265. ip->ip_off = 0;
  266. ip->ip_p = inp->inp_ip.ip_p;
  267. ip->ip_len = m->m_pkthdr.len;
  268. ip->ip_src = inp->inp_laddr;
  269. ip->ip_dst.s_addr = dst;
  270. ip->ip_ttl = inp->inp_ip.ip_ttl;
  271. opts = inp->inp_options;
  272. } else {
  273.         if (m->m_len < sizeof (struct ip) &&
  274.     (m = m_pullup (m, sizeof (struct ip))) == NULL)
  275.     {
  276.     return (ENOBUFS);
  277.     }
  278. ip = mtod(m, struct ip *);
  279. if (ip->ip_id == 0)
  280. #ifdef VIRTUAL_STACK
  281. ip->ip_id = htons(_ip_id++);
  282. #else
  283. ip->ip_id = htons(ip_id++);
  284. #endif /* VIRTUAL_STACK */
  285. opts = NULL;
  286. /* XXX prevent ip_output from overwriting header fields */
  287. flags |= IP_RAWOUTPUT;
  288. #ifdef VIRTUAL_STACK
  289. _ipstat.ips_rawout++;
  290. #else
  291. ipstat.ips_rawout++;
  292. #endif /* VIRTUAL_STACK */
  293. }
  294.     result = ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions);
  295. #ifdef WV_INSTRUMENTATION
  296. #ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */
  297.     WV_NET_ADDROUT_EVENT_3 (NET_CORE_EVENT, WV_NET_NOTICE, 15, 8,
  298.                             inp->inp_laddr.s_addr, dst,
  299.                             WV_NETEVENT_RAWIPOUT_FINISH, WV_NET_SEND,
  300.                             result, inp->inp_laddr.s_addr, dst)
  301. #endif  /* INCLUDE_WVNET */
  302. #endif
  303.     return (result);
  304. }
  305. /*
  306.  * Raw IP socket option processing.
  307.  */
  308. int
  309. rip_ctloutput(op, so, level, optname, m)
  310. int op;
  311. struct socket *so;
  312. int level, optname;
  313. struct mbuf **m;
  314. {
  315. register struct inpcb *inp = sotoinpcb(so);
  316. register int error;
  317. #ifdef WV_INSTRUMENTATION
  318. #ifdef INCLUDE_WVNET    /* WV_NET_INFO event */
  319.     WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_INFO, 13, 9,
  320.                      WV_NETEVENT_RAWCTLOUT_START,
  321.                      so->so_fd, op, level, optname)
  322. #endif  /* INCLUDE_WVNET */
  323. #endif
  324.         if (level == IPPROTO_ICMP)
  325.             return (icmp_ctloutput (op, so, level, optname, m));
  326. if (level != IPPROTO_IP) {
  327. if (op == PRCO_SETOPT && *m)
  328. (void) m_free(*m);
  329. #ifdef WV_INSTRUMENTATION
  330. #ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */
  331.                 WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_ERROR, 32, 2,
  332.                                  WV_NETEVENT_RAWCTLOUT_BADLEVEL,
  333.                                  so->so_fd, op, level, optname)
  334. #endif  /* INCLUDE_WVNET */
  335. #endif
  336. return (EINVAL);
  337. }
  338. switch (optname) {
  339. case IP_HDRINCL:
  340. error = 0;
  341. if (op == PRCO_SETOPT) {
  342. if (*m == 0 || (*m)->m_len < sizeof (int))
  343.                             {
  344. #ifdef WV_INSTRUMENTATION
  345. #ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */
  346.                     WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_ERROR, 33, 3,
  347.                                      WV_NETEVENT_RAWCTLOUT_BADMEM,
  348.                                      so->so_fd, op, level, optname)
  349. #endif  /* INCLUDE_WVNET */
  350. #endif
  351. error = EINVAL;
  352.                             }
  353. else if (*mtod(*m, int *))
  354. inp->inp_flags |= INP_HDRINCL;
  355. else
  356. inp->inp_flags &= ~INP_HDRINCL;
  357. if (*m)
  358. (void)m_free(*m);
  359. } else {
  360. *m = mBufClGet(M_WAIT, MT_SOOPTS, CL_SIZE_128, TRUE);
  361. if (*m == (struct mbuf *) NULL)
  362.     {
  363.     error = ENOBUFS;
  364.     }
  365. else
  366.     {
  367.     (*m)->m_len = sizeof (int);
  368.     *mtod(*m, int *) = inp->inp_flags & INP_HDRINCL;
  369.     }
  370. }
  371. return (error);
  372. case MRT_INIT:
  373. case MRT_DONE:
  374. case MRT_ADD_VIF:
  375. case MRT_DEL_VIF:
  376. case MRT_ADD_MFC:
  377. case MRT_DEL_MFC:
  378. case MRT_VERSION:
  379. case MRT_ASSERT:
  380.              return (_mCastCtlOutput (op, optname, so, m));
  381. default:
  382. if (optname >= MRT_INIT)
  383.              return (_mCastCtlOutput (op, optname, so, m));
  384. }
  385. return (ip_ctloutput(op, so, level, optname, m));
  386. }
  387. #ifndef VIRTUAL_STACK
  388. u_long rip_sendspace = RIPSNDQ;
  389. u_long rip_recvspace = RIPRCVQ;
  390. #endif /* VIRTUAL_STACK */
  391. /*ARGSUSED*/
  392. int
  393. rip_usrreq(so, req, m, nam, control)
  394. register struct socket *so;
  395. int req;
  396. struct mbuf *m, *nam, *control;
  397. {
  398. register int error = 0;
  399. register struct inpcb *inp = sotoinpcb(so);
  400. #ifdef WV_INSTRUMENTATION
  401. #ifdef INCLUDE_WVNET    /* WV_NET_INFO event */
  402.     WV_NET_MARKER_2 (NET_CORE_EVENT, WV_NET_INFO, 14, 10,
  403.                      WV_NETEVENT_RAWIPREQ_START, so->so_fd, req)
  404. #endif  /* INCLUDE_WVNET */
  405. #endif
  406.         if (req == PRU_CONTROL)
  407.             return (in_control(so, (u_long)m, (caddr_t)nam,
  408.                     (struct ifnet *)control));
  409. switch (req) {
  410. case PRU_ATTACH:
  411. if (inp)
  412.                     {
  413. #ifdef WV_INSTRUMENTATION
  414. #ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */
  415.                 WV_NET_MARKER_2 (NET_CORE_EVENT, WV_NET_EMERGENCY, 19, 1,
  416.                                  WV_NETEVENT_RAWIPREQ_PANIC, so->so_fd, req)
  417. #endif  /* INCLUDE_WVNET */
  418. #endif
  419. panic("rip_attach");
  420.                     }
  421. if ((so->so_state & SS_PRIV) == 0) {
  422. error = EACCES;
  423. break;
  424. }
  425. if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
  426.     (error = in_pcballoc(so, &ripcbinfo)))
  427. break;
  428. inp = (struct inpcb *)so->so_pcb;
  429. inp->inp_ip.ip_p = (int)nam;
  430. inp->inp_ip.ip_ttl = ip_defttl;
  431. break;
  432. case PRU_DISCONNECT:
  433. if ((so->so_state & SS_ISCONNECTED) == 0) {
  434. error = ENOTCONN;
  435. break;
  436. }
  437. /* FALLTHROUGH */
  438. case PRU_ABORT:
  439. soisdisconnected(so);
  440. /* FALLTHROUGH */
  441. case PRU_DETACH:
  442. if (inp == 0)
  443.                     {
  444. #ifdef WV_INSTRUMENTATION
  445. #ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */
  446.                 WV_NET_MARKER_2 (NET_CORE_EVENT, WV_NET_EMERGENCY, 19, 1,
  447.                                  WV_NETEVENT_RAWIPREQ_PANIC, so->so_fd, req)
  448. #endif  /* INCLUDE_WVNET */
  449. #endif
  450. panic("rip_detach");
  451.                     }
  452. in_pcbdetach(inp);
  453. break;
  454. case PRU_BIND:
  455.     {
  456. struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
  457. if (nam->m_len != sizeof(*addr)) {
  458. error = EINVAL;
  459. break;
  460. }
  461. #ifdef VIRTUAL_STACK
  462. if ((_ifnet == 0) ||
  463. #else
  464. if ((ifnet == 0) ||
  465. #endif /* VIRTUAL_STACK */
  466.     ((addr->sin_family != AF_INET) &&
  467.      (addr->sin_family != AF_IMPLINK)) ||
  468.     (addr->sin_addr.s_addr &&
  469.      ifa_ifwithaddr((struct sockaddr *)addr) == 0)) {
  470. error = EADDRNOTAVAIL;
  471. break;
  472. }
  473. inp->inp_laddr = addr->sin_addr;
  474. break;
  475.     }
  476. case PRU_CONNECT:
  477.     {
  478. struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
  479. if (nam->m_len != sizeof(*addr)) {
  480. error = EINVAL;
  481. break;
  482. }
  483. #ifdef VIRTUAL_STACK
  484. if (_ifnet == 0) {
  485. #else
  486. if (ifnet == 0) {
  487. #endif /* VIRTUAL_STACK */
  488. error = EADDRNOTAVAIL;
  489. break;
  490. }
  491. if ((addr->sin_family != AF_INET) &&
  492.      (addr->sin_family != AF_IMPLINK)) {
  493. error = EAFNOSUPPORT;
  494. break;
  495. }
  496. inp->inp_faddr = addr->sin_addr;
  497. soisconnected(so);
  498. break;
  499.     }
  500. case PRU_CONNECT2:
  501. error = EOPNOTSUPP;
  502. break;
  503. /*
  504.  * Mark the connection as being incapable of further input.
  505.  */
  506. case PRU_SHUTDOWN:
  507. socantsendmore(so);
  508. break;
  509. /*
  510.  * Ship a packet out.  The appropriate raw output
  511.  * routine handles any massaging necessary.
  512.  */
  513. case PRU_SEND:
  514.     {
  515. register u_long dst;
  516. if (so->so_state & SS_ISCONNECTED) {
  517. if (nam) {
  518. error = EISCONN;
  519. break;
  520. }
  521. dst = inp->inp_faddr.s_addr;
  522. } else {
  523. if (nam == NULL) {
  524. error = ENOTCONN;
  525. break;
  526. }
  527. dst = mtod(nam, struct sockaddr_in *)->sin_addr.s_addr;
  528. }
  529. error = rip_output(m, so, dst);
  530. m = NULL;
  531. break;
  532.     }
  533. case PRU_SENSE:
  534. /*
  535.  * stat: don't bother with a blocksize.
  536.  */
  537. return (0);
  538. /*
  539.  * Not supported.
  540.  */
  541. case PRU_RCVOOB:
  542. case PRU_RCVD:
  543. case PRU_LISTEN:
  544. case PRU_ACCEPT:
  545. case PRU_SENDOOB:
  546. error = EOPNOTSUPP;
  547. break;
  548. case PRU_SOCKADDR:
  549. in_setsockaddr(inp, nam);
  550. break;
  551. case PRU_PEERADDR:
  552. in_setpeeraddr(inp, nam);
  553. break;
  554. default:
  555. #ifdef WV_INSTRUMENTATION
  556. #ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */
  557.             WV_NET_MARKER_2 (NET_CORE_EVENT, WV_NET_EMERGENCY, 19, 1,
  558.                              WV_NETEVENT_RAWIPREQ_PANIC, so->so_fd, req)
  559. #endif  /* INCLUDE_WVNET */
  560. #endif
  561. panic("rip_usrreq");
  562. }
  563. if (m != NULL)
  564. m_freem(m);
  565. #ifdef WV_INSTRUMENTATION
  566. #ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */
  567.     if (error)
  568.         {
  569.         WV_NET_MARKER_3 (NET_CORE_EVENT, WV_NET_ERROR, 34, 4,
  570.                          WV_NETEVENT_RAWIPREQ_FAIL, so->so_fd, req, error)
  571.         }
  572. #endif  /* INCLUDE_WVNET */
  573. #endif
  574. return (error);
  575. }
  576. /*******************************************************************************
  577. * mCastCtlOutput - send commands to multicast routing engine.
  578. *
  579. * This function sends commands to multicast routing engine.
  580. *
  581. * INTERNAL
  582. * This function can be further expanded to receive multicast options also.
  583. * That is the reason for passing a pointer to a pointer to an mbuf as one of
  584. * the argument.
  585. *
  586. * RETURNS: OK/ERROR
  587. *
  588. * NOMANUAL
  589. */
  590. static int _mCastCtlOutput
  591.     (
  592.     int  option, /* type of option */
  593.     int  optName, /* name of the option */
  594.     struct socket *  sockPtr, /* pointer to the socket */
  595.     struct mbuf ** pPtrMbuf /* pointer to pointer to an mbuf */
  596.     )
  597.     {
  598.     register int error = EINVAL; /* default error value */
  599.     if (pPtrMbuf == NULL)
  600.         return (error);
  601.     
  602.     if (option == PRCO_SETOPT)
  603.         {
  604.         if (_mCastRouteCmdHook != NULL)
  605.             error = (*_mCastRouteCmdHook)(optName, sockPtr, *pPtrMbuf);
  606.         else
  607.             error = EOPNOTSUPP; 
  608.         }
  609.     if (*pPtrMbuf != NULL)
  610.         (void) m_free (*pPtrMbuf);
  611.     return (error);
  612.     }