Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/raw_ip.c,v retrieving revision 1.59 retrieving revision 1.60 diff -u -p -r1.59 -r1.60 --- src/sys/netinet/raw_ip.c 2001/11/13 00:32:40 1.59 +++ src/sys/netinet/raw_ip.c 2001/12/21 02:51:47 1.60 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_ip.c,v 1.59 2001/11/13 00:32:40 lukem Exp $ */ +/* $NetBSD: raw_ip.c,v 1.60 2001/12/21 02:51:47 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -65,7 +65,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.59 2001/11/13 00:32:40 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.60 2001/12/21 02:51:47 itojun Exp $"); #include "opt_ipsec.h" #include "opt_mrouting.h" @@ -100,6 +100,8 @@ __KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1 struct inpcbtable rawcbtable; +int rip_pcbnotify __P((struct inpcbtable *, struct in_addr, + struct in_addr, int, int, void (*) __P((struct inpcb *, int)))); int rip_bind __P((struct inpcb *, struct mbuf *)); int rip_connect __P((struct inpcb *, struct mbuf *)); void rip_disconnect __P((struct inpcb *)); @@ -233,6 +235,67 @@ rip_input(m, va_alist) return; } +int +rip_pcbnotify(table, faddr, laddr, proto, errno, notify) + struct inpcbtable *table; + struct in_addr faddr, laddr; + int proto; + int errno; + void (*notify) __P((struct inpcb *, int)); +{ + struct inpcb *inp, *ninp; + int nmatch; + + nmatch = 0; + for (inp = CIRCLEQ_FIRST(&table->inpt_queue); + inp != (struct inpcb *)&table->inpt_queue; + inp = ninp) { + ninp = inp->inp_queue.cqe_next; + if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != proto) + continue; + if (in_hosteq(inp->inp_faddr, faddr) && + in_hosteq(inp->inp_laddr, laddr)) { + (*notify)(inp, errno); + nmatch++; + } + } + + return nmatch; +} + +void * +rip_ctlinput(cmd, sa, v) + int cmd; + struct sockaddr *sa; + void *v; +{ + struct ip *ip = v; + void (*notify) __P((struct inpcb *, int)) = in_rtchange; + int errno; + + if (sa->sa_family != AF_INET || + sa->sa_len != sizeof(struct sockaddr_in)) + return NULL; + if ((unsigned)cmd >= PRC_NCMDS) + return NULL; + errno = inetctlerrmap[cmd]; + if (PRC_IS_REDIRECT(cmd)) + notify = in_rtchange, ip = 0; + else if (cmd == PRC_HOSTDEAD) + ip = 0; + else if (errno == 0) + return NULL; + if (ip) { + rip_pcbnotify(&rawcbtable, satosin(sa)->sin_addr, + ip->ip_src, ip->ip_p, errno, notify); + + /* XXX mapped address case */ + } else + in_pcbnotifyall(&rawcbtable, satosin(sa)->sin_addr, errno, + notify); + return NULL; +} + /* * Generate IP header and pass packet to ip_output. * Tack on options user may have setup with control call.