+ register int error = 0;
+ register struct rawisopcb *rp = sotorawisopcb(so);
+
+ rp = sotorawisopcb(so);
+ switch (req) {
+
+ case PRU_ATTACH:
+ if (rp)
+ panic("rip_attach");
+ MALLOC(rp, struct rawisopcb *, 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->risop_isop.isop_options)
+ m_freem(rp->risop_isop.isop_options);
+ if (rp->risop_isop.isop_route.ro_rt)
+ RTFREE(rp->risop_isop.isop_route.ro_rt);
+ if (rp->risop_rcb.rcb_laddr)
+ rp->risop_rcb.rcb_laddr = 0;
+ /* free clnp cached hdr if necessary */
+ if (rp->risop_isop.isop_clnpcache != NULL) {
+ struct clnp_cache *clcp =
+ mtod(rp->risop_isop.isop_clnpcache, struct clnp_cache *);
+ if (clcp->clc_hdr != NULL) {
+ m_free(clcp->clc_hdr);
+ }
+ m_free(rp->risop_isop.isop_clnpcache);
+ }
+ if (rp->risop_isop.isop_optindex != NULL)
+ m_free(rp->risop_isop.isop_optindex);
+
+ break;
+
+ case PRU_BIND:
+ {
+ struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
+
+ if (nam->m_len != sizeof(*addr))
+ return (EINVAL);
+ if ((ifnet == 0) ||
+ (addr->siso_family != AF_ISO) ||
+ (addr->siso_addr.isoa_len &&
+ ifa_ifwithaddr((struct sockaddr *)addr) == 0))
+ return (EADDRNOTAVAIL);
+ rp->risop_isop.isop_sladdr = *addr;
+ rp->risop_rcb.rcb_laddr = (struct sockaddr *)
+ (rp->risop_isop.isop_laddr = &rp->risop_isop.isop_sladdr);
+ return (0);
+ }
+ case PRU_CONNECT:
+ {
+ struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
+
+ if ((nam->m_len > sizeof(*addr)) || (addr->siso_len > sizeof(*addr)))
+ return (EINVAL);
+ if (ifnet == 0)
+ return (EADDRNOTAVAIL);
+ if (addr->siso_family != AF_ISO)
+ rp->risop_isop.isop_sfaddr = *addr;
+ rp->risop_rcb.rcb_faddr = (struct sockaddr *)
+ (rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr);
+ soisconnected(so);
+ return (0);
+ }
+ }
+ error = raw_usrreq(so, req, m, nam, control);
+
+ if (error && req == PRU_ATTACH && so->so_pcb)
+ free((caddr_t)rp, M_PCB);
+ return (error);