version 1.25.4.2, 1996/12/11 04:01:08 |
version 1.41.6.1, 1998/12/11 04:53:09 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
* |
* |
* @(#)raw_ip.c 8.2 (Berkeley) 1/4/94 |
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95 |
*/ |
*/ |
|
|
|
#include "opt_mrouting.h" |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/malloc.h> |
#include <sys/malloc.h> |
#include <sys/mbuf.h> |
#include <sys/mbuf.h> |
|
|
rip_init() |
rip_init() |
{ |
{ |
|
|
in_pcbinit(&rawcbtable, 1); |
in_pcbinit(&rawcbtable, 1, 1); |
} |
} |
|
|
struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET }; |
|
/* |
/* |
* Setup generic address and protocol structures |
* Setup generic address and protocol structures |
* for raw_input routine, then pass them along with |
* for raw_input routine, then pass them along with |
Line 101 rip_input(m, va_alist) |
|
Line 102 rip_input(m, va_alist) |
|
{ |
{ |
register struct ip *ip = mtod(m, struct ip *); |
register struct ip *ip = mtod(m, struct ip *); |
register struct inpcb *inp; |
register struct inpcb *inp; |
struct socket *last = 0; |
struct inpcb *last = 0; |
|
struct mbuf *opts = 0; |
|
struct sockaddr_in ripsrc; |
|
|
|
ripsrc.sin_family = AF_INET; |
|
ripsrc.sin_len = sizeof(struct sockaddr_in); |
ripsrc.sin_addr = ip->ip_src; |
ripsrc.sin_addr = ip->ip_src; |
|
ripsrc.sin_port = 0; |
|
bzero((caddr_t)ripsrc.sin_zero, sizeof(ripsrc.sin_zero)); |
|
|
for (inp = rawcbtable.inpt_queue.cqh_first; |
for (inp = rawcbtable.inpt_queue.cqh_first; |
inp != (struct inpcb *)&rawcbtable.inpt_queue; |
inp != (struct inpcb *)&rawcbtable.inpt_queue; |
inp = inp->inp_queue.cqe_next) { |
inp = inp->inp_queue.cqe_next) { |
if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p) |
if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p) |
continue; |
continue; |
if (inp->inp_laddr.s_addr != INADDR_ANY && |
if (!in_nullhost(inp->inp_laddr) && |
inp->inp_laddr.s_addr != ip->ip_dst.s_addr) |
!in_hosteq(inp->inp_laddr, ip->ip_dst)) |
continue; |
continue; |
if (inp->inp_faddr.s_addr != INADDR_ANY && |
if (!in_nullhost(inp->inp_faddr) && |
inp->inp_faddr.s_addr != ip->ip_src.s_addr) |
!in_hosteq(inp->inp_faddr, ip->ip_src)) |
continue; |
continue; |
if (last) { |
if (last) { |
struct mbuf *n; |
struct mbuf *n; |
if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) { |
if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) { |
if (sbappendaddr(&last->so_rcv, |
if (last->inp_flags & INP_CONTROLOPTS || |
sintosa(&ripsrc), n, |
last->inp_socket->so_options & SO_TIMESTAMP) |
(struct mbuf *)0) == 0) |
ip_savecontrol(last, &opts, ip, n); |
|
if (sbappendaddr(&last->inp_socket->so_rcv, |
|
sintosa(&ripsrc), n, opts) == 0) { |
/* should notify about lost packet */ |
/* should notify about lost packet */ |
m_freem(n); |
m_freem(n); |
else |
if (opts) |
sorwakeup(last); |
m_freem(opts); |
|
} else |
|
sorwakeup(last->inp_socket); |
|
opts = NULL; |
} |
} |
} |
} |
last = inp->inp_socket; |
last = inp; |
} |
} |
if (last) { |
if (last) { |
if (sbappendaddr(&last->so_rcv, sintosa(&ripsrc), m, |
if (last->inp_flags & INP_CONTROLOPTS || |
(struct mbuf *)0) == 0) |
last->inp_socket->so_options & SO_TIMESTAMP) |
|
ip_savecontrol(last, &opts, ip, m); |
|
if (sbappendaddr(&last->inp_socket->so_rcv, |
|
sintosa(&ripsrc), m, opts) == 0) { |
m_freem(m); |
m_freem(m); |
else |
if (opts) |
sorwakeup(last); |
m_freem(opts); |
|
} else |
|
sorwakeup(last->inp_socket); |
} else { |
} else { |
m_freem(m); |
m_freem(m); |
ipstat.ips_noproto++; |
ipstat.ips_noproto++; |
Line 166 rip_output(m, va_alist) |
|
Line 184 rip_output(m, va_alist) |
|
va_end(ap); |
va_end(ap); |
|
|
flags = |
flags = |
(inp->inp_socket->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST; |
(inp->inp_socket->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST |
|
| IP_RETURNMTU; |
|
|
/* |
/* |
* If the user handed us a complete IP packet, use it. |
* If the user handed us a complete IP packet, use it. |
Line 193 rip_output(m, va_alist) |
|
Line 212 rip_output(m, va_alist) |
|
return (EMSGSIZE); |
return (EMSGSIZE); |
} |
} |
ip = mtod(m, struct ip *); |
ip = mtod(m, struct ip *); |
|
if (m->m_pkthdr.len != ip->ip_len) { |
|
m_freem(m); |
|
return (EINVAL); |
|
} |
if (ip->ip_id == 0) |
if (ip->ip_id == 0) |
ip->ip_id = htons(ip_id++); |
ip->ip_id = htons(ip_id++); |
opts = NULL; |
opts = NULL; |
Line 200 rip_output(m, va_alist) |
|
Line 223 rip_output(m, va_alist) |
|
flags |= IP_RAWOUTPUT; |
flags |= IP_RAWOUTPUT; |
ipstat.ips_rawout++; |
ipstat.ips_rawout++; |
} |
} |
return (ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions)); |
return (ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions, &inp->inp_errormtu)); |
} |
} |
|
|
/* |
/* |
Line 285 rip_bind(inp, nam) |
|
Line 308 rip_bind(inp, nam) |
|
struct mbuf *nam; |
struct mbuf *nam; |
{ |
{ |
struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); |
struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); |
|
struct ifaddr *ifa = NULL; |
|
|
if (nam->m_len != sizeof(*addr)) |
if (nam->m_len != sizeof(*addr)) |
return (EINVAL); |
return (EINVAL); |
Line 293 rip_bind(inp, nam) |
|
Line 317 rip_bind(inp, nam) |
|
if (addr->sin_family != AF_INET && |
if (addr->sin_family != AF_INET && |
addr->sin_family != AF_IMPLINK) |
addr->sin_family != AF_IMPLINK) |
return (EAFNOSUPPORT); |
return (EAFNOSUPPORT); |
if (addr->sin_addr.s_addr != INADDR_ANY && |
if (!in_nullhost(addr->sin_addr) && |
ifa_ifwithaddr(sintosa(addr)) == 0) |
(ifa = ifa_ifwithaddr(sintosa(addr))) == 0) |
return (EADDRNOTAVAIL); |
return (EADDRNOTAVAIL); |
inp->inp_laddr = addr->sin_addr; |
inp->inp_laddr = addr->sin_addr; |
|
if (ifa != NULL) |
|
ifa_delref(ifa); |
return (0); |
return (0); |
} |
} |
|
|
Line 323 rip_disconnect(inp) |
|
Line 349 rip_disconnect(inp) |
|
struct inpcb *inp; |
struct inpcb *inp; |
{ |
{ |
|
|
inp->inp_faddr.s_addr = INADDR_ANY; |
inp->inp_faddr = zeroin_addr; |
} |
} |
|
|
u_long rip_sendspace = RIPSNDQ; |
u_long rip_sendspace = RIPSNDQ; |