📄 raw_ip.c
字号:
int op; struct socket *so; int level, optname; struct mbuf **m;{ register struct inpcb *inp = sotoinpcb(so); register int error;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_INFO event */ WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_INFO, 13, 9, WV_NETEVENT_RAWCTLOUT_START, so->so_fd, op, level, optname)#endif /* INCLUDE_WVNET */#endif if (level == IPPROTO_ICMP) return (icmp_ctloutput (op, so, level, optname, m)); if (level != IPPROTO_IP) { if (op == PRCO_SETOPT && *m) (void) m_free(*m);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_ERROR event */ WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_ERROR, 32, 2, WV_NETEVENT_RAWCTLOUT_BADLEVEL, so->so_fd, op, level, optname)#endif /* INCLUDE_WVNET */#endif return (EINVAL); } switch (optname) { case IP_HDRINCL: error = 0; if (op == PRCO_SETOPT) { if (*m == 0 || (*m)->m_len < sizeof (int)) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_ERROR event */ WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_ERROR, 33, 3, WV_NETEVENT_RAWCTLOUT_BADMEM, so->so_fd, op, level, optname)#endif /* INCLUDE_WVNET */#endif error = EINVAL; } else if (*mtod(*m, int *)) inp->inp_flags |= INP_HDRINCL; else inp->inp_flags &= ~INP_HDRINCL; if (*m) (void)m_free(*m); } else { *m = mBufClGet(M_WAIT, MT_SOOPTS, CL_SIZE_128, TRUE); if (*m == (struct mbuf *) NULL) { error = ENOBUFS; } else { (*m)->m_len = sizeof (int); *mtod(*m, int *) = inp->inp_flags & INP_HDRINCL; } } return (error); case MRT_INIT: case MRT_DONE: case MRT_ADD_VIF: case MRT_DEL_VIF: case MRT_ADD_MFC: case MRT_DEL_MFC: case MRT_VERSION: case MRT_ASSERT: return (_mCastCtlOutput (op, optname, so, m)); default: if (optname >= MRT_INIT) return (_mCastCtlOutput (op, optname, so, m)); } return (ip_ctloutput(op, so, level, optname, m));}#ifndef VIRTUAL_STACKu_long rip_sendspace = RIPSNDQ;u_long rip_recvspace = RIPRCVQ;#endif /* VIRTUAL_STACK *//*ARGSUSED*/intrip_usrreq(so, req, m, nam, control) register struct socket *so; int req; struct mbuf *m, *nam, *control;{ register int error = 0; register struct inpcb *inp = sotoinpcb(so);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_INFO event */ WV_NET_MARKER_2 (NET_CORE_EVENT, WV_NET_INFO, 14, 10, WV_NETEVENT_RAWIPREQ_START, so->so_fd, req)#endif /* INCLUDE_WVNET */#endif if (req == PRU_CONTROL) return (in_control(so, (u_long)m, (caddr_t)nam, (struct ifnet *)control)); switch (req) { case PRU_ATTACH: if (inp) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_EMERGENCY event */ WV_NET_MARKER_2 (NET_CORE_EVENT, WV_NET_EMERGENCY, 19, 1, WV_NETEVENT_RAWIPREQ_PANIC, so->so_fd, req)#endif /* INCLUDE_WVNET */#endif panic("rip_attach"); } if ((so->so_state & SS_PRIV) == 0) { error = EACCES; break; } if ((error = soreserve(so, rip_sendspace, rip_recvspace)) || (error = in_pcballoc(so, &ripcbinfo))) break; inp = (struct inpcb *)so->so_pcb; inp->inp_ip.ip_p = (int)nam; inp->inp_ip.ip_ttl = ip_defttl; break; case PRU_DISCONNECT: if ((so->so_state & SS_ISCONNECTED) == 0) { error = ENOTCONN; break; } /* FALLTHROUGH */ case PRU_ABORT: soisdisconnected(so); /* FALLTHROUGH */ case PRU_DETACH: if (inp == 0) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_EMERGENCY event */ WV_NET_MARKER_2 (NET_CORE_EVENT, WV_NET_EMERGENCY, 19, 1, WV_NETEVENT_RAWIPREQ_PANIC, so->so_fd, req)#endif /* INCLUDE_WVNET */#endif panic("rip_detach"); } in_pcbdetach(inp); break; case PRU_BIND: { struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); if (nam->m_len != sizeof(*addr)) { error = EINVAL; break; }#ifdef VIRTUAL_STACK if ((_ifnet == 0) ||#else if ((ifnet == 0) ||#endif /* VIRTUAL_STACK */ ((addr->sin_family != AF_INET) && (addr->sin_family != AF_IMPLINK)) || (addr->sin_addr.s_addr && ifa_ifwithaddr((struct sockaddr *)addr) == 0)) { error = EADDRNOTAVAIL; break; } inp->inp_laddr = addr->sin_addr; break; } case PRU_CONNECT: { struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); if (nam->m_len != sizeof(*addr)) { error = EINVAL; break; }#ifdef VIRTUAL_STACK if (_ifnet == 0) {#else if (ifnet == 0) {#endif /* VIRTUAL_STACK */ error = EADDRNOTAVAIL; break; } if ((addr->sin_family != AF_INET) && (addr->sin_family != AF_IMPLINK)) { error = EAFNOSUPPORT; break; } inp->inp_faddr = addr->sin_addr; soisconnected(so); break; } case PRU_CONNECT2: error = EOPNOTSUPP; break; /* * Mark the connection as being incapable of further input. */ case PRU_SHUTDOWN: socantsendmore(so); break; /* * Ship a packet out. The appropriate raw output * routine handles any massaging necessary. */ case PRU_SEND: { register u_long dst; if (so->so_state & SS_ISCONNECTED) { if (nam) { error = EISCONN; break; } dst = inp->inp_faddr.s_addr; } else { if (nam == NULL) { error = ENOTCONN; break; } dst = mtod(nam, struct sockaddr_in *)->sin_addr.s_addr; } error = rip_output(m, so, dst); m = NULL; break; } case PRU_SENSE: /* * stat: don't bother with a blocksize. */ return (0); /* * Not supported. */ case PRU_RCVOOB: case PRU_RCVD: case PRU_LISTEN: case PRU_ACCEPT: case PRU_SENDOOB: error = EOPNOTSUPP; break; case PRU_SOCKADDR: in_setsockaddr(inp, nam); break; case PRU_PEERADDR: in_setpeeraddr(inp, nam); break; default:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_EMERGENCY event */ WV_NET_MARKER_2 (NET_CORE_EVENT, WV_NET_EMERGENCY, 19, 1, WV_NETEVENT_RAWIPREQ_PANIC, so->so_fd, req)#endif /* INCLUDE_WVNET */#endif panic("rip_usrreq"); } if (m != NULL) m_freem(m);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_ERROR event */ if (error) { WV_NET_MARKER_3 (NET_CORE_EVENT, WV_NET_ERROR, 34, 4, WV_NETEVENT_RAWIPREQ_FAIL, so->so_fd, req, error) }#endif /* INCLUDE_WVNET */#endif return (error);}/******************************************************************************** mCastCtlOutput - send commands to multicast routing engine.** This function sends commands to multicast routing engine.** INTERNAL* This function can be further expanded to receive multicast options also.* That is the reason for passing a pointer to a pointer to an mbuf as one of* the argument.** RETURNS: OK/ERROR** NOMANUAL*/static int _mCastCtlOutput ( int option, /* type of option */ int optName, /* name of the option */ struct socket * sockPtr, /* pointer to the socket */ struct mbuf ** pPtrMbuf /* pointer to pointer to an mbuf */ ) { register int error = EINVAL; /* default error value */ if (pPtrMbuf == NULL) return (error); if (option == PRCO_SETOPT) { if (_mCastRouteCmdHook != NULL) error = (*_mCastRouteCmdHook)(optName, sockPtr, *pPtrMbuf); else error = EOPNOTSUPP; } if (*pPtrMbuf != NULL) (void) m_free (*pPtrMbuf); return (error); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -