-
-/*ARGSUSED*/
-rip_usrreq(so, req, m, nam, rights, control)
- register struct socket *so;
- int req;
- struct mbuf *m, *nam, *rights, *control;
-{
- register int error = 0;
- register struct raw_inpcb *rp = sotorawinpcb(so);
-
- switch (req) {
-
- 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);
- }
- }
- error = raw_usrreq(so, req, m, nam, rights, control);
-
- if (error && (req == PRU_ATTACH) && so->so_pcb)
- free(so->so_pcb, M_PCB);
- return (error);
-}