+
+ case PRU_ATTACH:
+ if (rp)
+ panic("rip_attach");
+ MALLOC(rp, struct raw_inpcb *, sizeof *rp, M_PCB, M_WAITOK);
+ if (rp == 0)
+ return (ENOBUFS);
+ bzero((caddr_t)rp, sizeof *rp);
+ so->so_pcb = (caddr_t)rp;
+ break;
+
+ case PRU_DETACH:
+ if (rp == 0)
+ panic("rip_detach");
+ if (rp->rinp_options)
+ m_freem(rp->rinp_options);
+ if (rp->rinp_route.ro_rt)
+ RTFREE(rp->rinp_route.ro_rt);
+ if (rp->rinp_rcb.rcb_laddr)
+ rp->rinp_rcb.rcb_laddr = 0;
+ break;
+
+ case PRU_BIND:
+ {
+ struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
+
+ if (nam->m_len != sizeof(*addr))
+ return (EINVAL);
+ if ((ifnet == 0) ||
+ ((addr->sin_family != AF_INET) &&
+ (addr->sin_family != AF_IMPLINK)) ||
+ (addr->sin_addr.s_addr &&
+ ifa_ifwithaddr((struct sockaddr *)addr) == 0))
+ return (EADDRNOTAVAIL);
+ rp->rinp_rcb.rcb_laddr = (struct sockaddr *)&rp->rinp_laddr;
+ rp->rinp_laddr = *addr;
+ return (0);
+ }
+ case PRU_CONNECT:
+ {
+ struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
+
+ if (nam->m_len != sizeof(*addr))
+ return (EINVAL);
+ if (ifnet == 0)
+ return (EADDRNOTAVAIL);
+ if ((addr->sin_family != AF_INET) &&
+ (addr->sin_family != AF_IMPLINK))
+ return (EAFNOSUPPORT);
+ rp->rinp_rcb.rcb_faddr = (struct sockaddr *)&rp->rinp_faddr;
+ rp->rinp_laddr = *addr;
+ soisconnected(so);
+ return (0);
+ }