📄 iso_pcb.c
字号:
printf("iso_pcbconnect localzero 1\n"); ENDDEBUG /* * If route is known or can be allocated now, * our src addr is taken from the i/f, else punt. */ flags = isop->isop_socket->so_options & SO_DONTROUTE; if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags, (struct sockaddr **)0, &ia)) return error; IFDEBUG(D_ISO) printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x", isop->isop_route.ro_rt); printf(" ia 0x%x\n", ia); ENDDEBUG } IFDEBUG(D_ISO) printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", isop, isop->isop_socket); ENDDEBUG if (local_zero) { int nlen, tlen, totlen; caddr_t oldtsel, newtsel; siso = isop->isop_laddr; if (siso == 0 || siso->siso_tlen == 0) (void)iso_pcbbind(isop, (struct mbuf *)0); /* * Here we have problem of squezeing in a definite network address * into an existing sockaddr_iso, which in fact may not have room * for it. This gets messy. */ siso = isop->isop_laddr; oldtsel = TSEL(siso); tlen = siso->siso_tlen; nlen = ia->ia_addr.siso_nlen; totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]); if ((siso == &isop->isop_sladdr) && (totlen > sizeof(isop->isop_sladdr))) { struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); if (m == 0) return ENOBUFS; m->m_len = totlen; isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *); } siso->siso_nlen = ia->ia_addr.siso_nlen; newtsel = TSEL(siso); ovbcopy(oldtsel, newtsel, tlen); bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen); siso->siso_tlen = tlen; siso->siso_family = AF_ISO; siso->siso_len = totlen; siso = mtod(nam, struct sockaddr_iso *); } IFDEBUG(D_ISO) printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", isop, isop->isop_socket); ENDDEBUG /* * If we had to allocate space to a previous big foreign address, * and for some reason we didn't free it, we reuse it knowing * that is going to be big enough, as sockaddrs are delivered in * 128 byte mbufs. * If the foreign address is small enough, we use default space; * otherwise, we grab an mbuf to copy into. */ if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) { if (siso->siso_len <= sizeof(isop->isop_sfaddr)) isop->isop_faddr = &isop->isop_sfaddr; else { struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); if (m == 0) return ENOBUFS; isop->isop_faddr = mtod(m, struct sockaddr_iso *); } } bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len); IFDEBUG(D_ISO) printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", isop, isop->isop_socket); printf("iso_pcbconnect connected to addr:\n"); dump_isoaddr(isop->isop_faddr); printf("iso_pcbconnect end: src addr:\n"); dump_isoaddr(isop->isop_laddr); ENDDEBUG return 0;}/* * FUNCTION: iso_pcbdisconnect() * * PURPOSE: washes away the peer address info so the socket * appears to be disconnected. * If there's no file descriptor associated with the socket * it detaches the pcb. * * RETURNS: Nada. * * SIDE EFFECTS: May detach the pcb. * * NOTES: */voidiso_pcbdisconnect(isop) struct isopcb *isop;{ void iso_pcbdetach(); register struct sockaddr_iso *siso; IFDEBUG(D_ISO) printf("iso_pcbdisconnect(isop 0x%x)\n", isop); ENDDEBUG /* * Preserver binding infnormation if already bound. */ if ((siso = isop->isop_laddr) && siso->siso_nlen && siso->siso_tlen) { caddr_t otsel = TSEL(siso); siso->siso_nlen = 0; ovbcopy(otsel, TSEL(siso), siso->siso_tlen); } if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr) m_freem(dtom(isop->isop_faddr)); isop->isop_faddr = 0; if (isop->isop_socket->so_state & SS_NOFDREF) iso_pcbdetach(isop);}/* * FUNCTION: iso_pcbdetach * * PURPOSE: detach the pcb at *(isop) from it's socket and free * the mbufs associated with the pcb.. * Dequeues (isop) from its head. * * RETURNS: Nada. * * SIDE EFFECTS: * * NOTES: */voidiso_pcbdetach(isop) struct isopcb *isop;{ struct socket *so = isop->isop_socket; IFDEBUG(D_ISO) printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", isop, isop->isop_socket, so); ENDDEBUG#ifdef TPCONS if (isop->isop_chan) { register struct pklcd *lcp = (struct pklcd *)isop->isop_chan; if (--isop->isop_refcnt > 0) return; if (lcp && lcp->lcd_state == DATA_TRANSFER) { lcp->lcd_upper = 0; lcp->lcd_upnext = 0; pk_disconnect(lcp); } isop->isop_chan = 0; }#endif if (so) { /* in the x.25 domain, we sometimes have no socket */ so->so_pcb = 0; sofree(so); } IFDEBUG(D_ISO) printf("iso_pcbdetach 2 \n"); ENDDEBUG if (isop->isop_options) (void)m_free(isop->isop_options); IFDEBUG(D_ISO) printf("iso_pcbdetach 3 \n"); ENDDEBUG if (isop->isop_route.ro_rt) rtfree(isop->isop_route.ro_rt); IFDEBUG(D_ISO) printf("iso_pcbdetach 3.1\n"); ENDDEBUG if (isop->isop_clnpcache != NULL) { struct clnp_cache *clcp = mtod(isop->isop_clnpcache, struct clnp_cache *); IFDEBUG(D_ISO) printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", clcp, clcp->clc_hdr); ENDDEBUG if (clcp->clc_hdr != NULL) m_free(clcp->clc_hdr); IFDEBUG(D_ISO) printf("iso_pcbdetach 3.3: freeing cache x%x\n", isop->isop_clnpcache); ENDDEBUG m_free(isop->isop_clnpcache); } IFDEBUG(D_ISO) printf("iso_pcbdetach 4 \n"); ENDDEBUG remque(isop); IFDEBUG(D_ISO) printf("iso_pcbdetach 5 \n"); ENDDEBUG if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr)) m_freem(dtom(isop->isop_laddr)); free((caddr_t)isop, M_PCB);}/* * FUNCTION: iso_pcbnotify * * PURPOSE: notify all connections in this protocol's queue (head) * that have peer address (dst) of the problem (errno) * by calling (notify) on the connections' isopcbs. * * RETURNS: Rien. * * SIDE EFFECTS: * * NOTES: (notify) is called at splimp! */voidiso_pcbnotify(head, siso, errno, notify) struct isopcb *head; register struct sockaddr_iso *siso; int errno, (*notify)();{ register struct isopcb *isop; int s = splimp(); IFDEBUG(D_ISO) printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify); ENDDEBUG for (isop = head->isop_next; isop != head; isop = isop->isop_next) { if (isop->isop_socket == 0 || isop->isop_faddr == 0 || !SAME_ISOADDR(siso, isop->isop_faddr)) { IFDEBUG(D_ISO) printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" , isop, isop->isop_socket); printf("addrmatch cmp'd with (0x%x):\n", isop->isop_faddr); dump_isoaddr(isop->isop_faddr); ENDDEBUG continue; } if (errno) isop->isop_socket->so_error = errno; if (notify) (*notify)(isop); } splx(s); IFDEBUG(D_ISO) printf("END OF iso_pcbnotify\n" ); ENDDEBUG}/* * FUNCTION: iso_pcblookup * * PURPOSE: looks for a given combination of (faddr), (fport), * (lport), (laddr) in the queue named by (head). * Argument (flags) is ignored. * * RETURNS: ptr to the isopcb if it finds a connection matching * these arguments, o.w. returns zero. * * SIDE EFFECTS: * * NOTES: */struct isopcb *iso_pcblookup(head, fportlen, fport, laddr) struct isopcb *head; register struct sockaddr_iso *laddr; caddr_t fport; int fportlen;{ register struct isopcb *isop; register caddr_t lp = TSEL(laddr); unsigned int llen = laddr->siso_tlen; IFDEBUG(D_ISO) printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", head, laddr, fport); ENDDEBUG for (isop = head->isop_next; isop != head; isop = isop->isop_next) { if (isop->isop_laddr == 0 || isop->isop_laddr == laddr) continue; if (isop->isop_laddr->siso_tlen != llen) continue; if (bcmp(lp, TSEL(isop->isop_laddr), llen)) continue; if (fportlen && isop->isop_faddr && bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen)) continue; /* PHASE2 * addrmatch1 should be iso_addrmatch(a, b, mask) * where mask is taken from isop->isop_laddrmask (new field) * isop_lnetmask will also be available in isop if (laddr != &zeroiso_addr && !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr))) continue; */ if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr))) continue; return (isop); } return (struct isopcb *)0;}#endif /* ISO */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -