📄 iso.c
字号:
return (ENOBUFS); bzero((caddr_t)nia, sizeof(*nia)); if (ia = iso_ifaddr) { for ( ; ia->ia_next; ia = ia->ia_next) ; ia->ia_next = nia; } else iso_ifaddr = nia; ia = nia; if (ifa = ifp->if_addrlist) { for ( ; ifa->ifa_next; ifa = ifa->ifa_next) ; ifa->ifa_next = (struct ifaddr *) ia; } else ifp->if_addrlist = (struct ifaddr *) ia; ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_sockmask; ia->ia_ifp = ifp; if (ifp != &loif) iso_interfaces++; } break;#define cmdbyte(x) (((x) >> 8) & 0xff) default: if (cmdbyte(cmd) == 'a') return (snpac_ioctl(so, cmd, data)); if (ia == (struct iso_ifaddr *)0) return (EADDRNOTAVAIL); break; } switch (cmd) { case SIOCGIFADDR_ISO: ifr->ifr_Addr = ia->ia_addr; break; case SIOCGIFDSTADDR_ISO: if ((ifp->if_flags & IFF_POINTOPOINT) == 0) return (EINVAL); ifr->ifr_Addr = ia->ia_dstaddr; break; case SIOCGIFNETMASK_ISO: ifr->ifr_Addr = ia->ia_sockmask; break; case SIOCAIFADDR_ISO: maskIsNew = 0; hostIsNew = 1; error = 0; if (ia->ia_addr.siso_family == AF_ISO) { if (ifra->ifra_addr.siso_len == 0) { ifra->ifra_addr = ia->ia_addr; hostIsNew = 0; } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) hostIsNew = 0; } if (ifra->ifra_mask.siso_len) { iso_ifscrub(ifp, ia); ia->ia_sockmask = ifra->ifra_mask; maskIsNew = 1; } if ((ifp->if_flags & IFF_POINTOPOINT) && (ifra->ifra_dstaddr.siso_family == AF_ISO)) { iso_ifscrub(ifp, ia); ia->ia_dstaddr = ifra->ifra_dstaddr; maskIsNew = 1; /* We lie; but the effect's the same */ } if (ifra->ifra_addr.siso_family == AF_ISO && (hostIsNew || maskIsNew)) { error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0); } if (ifra->ifra_snpaoffset) ia->ia_snpaoffset = ifra->ifra_snpaoffset; return (error); case SIOCDIFADDR_ISO: iso_ifscrub(ifp, ia); if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia) ifp->if_addrlist = ifa->ifa_next; else { while (ifa->ifa_next && (ifa->ifa_next != (struct ifaddr *)ia)) ifa = ifa->ifa_next; if (ifa->ifa_next) ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next; else printf("Couldn't unlink isoifaddr from ifp\n"); } oia = ia; if (oia == (ia = iso_ifaddr)) { iso_ifaddr = ia->ia_next; } else { while (ia->ia_next && (ia->ia_next != oia)) { ia = ia->ia_next; } if (ia->ia_next) ia->ia_next = oia->ia_next; else printf("Didn't unlink isoifadr from list\n"); } IFAFREE((&oia->ia_ifa)); break; default: if (ifp == 0 || ifp->if_ioctl == 0) return (EOPNOTSUPP); return ((*ifp->if_ioctl)(ifp, cmd, data)); } return (0);}/* * Delete any existing route for an interface. */iso_ifscrub(ifp, ia) register struct ifnet *ifp; register struct iso_ifaddr *ia;{ int nsellength = ia->ia_addr.siso_tlen; if ((ia->ia_flags & IFA_ROUTE) == 0) return; ia->ia_addr.siso_tlen = 0; if (ifp->if_flags & IFF_LOOPBACK) rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); else if (ifp->if_flags & IFF_POINTOPOINT) rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); else { rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); } ia->ia_addr.siso_tlen = nsellength; ia->ia_flags &= ~IFA_ROUTE;}/* * Initialize an interface's internet address * and routing table entry. */iso_ifinit(ifp, ia, siso, scrub) register struct ifnet *ifp; register struct iso_ifaddr *ia; struct sockaddr_iso *siso;{ struct sockaddr_iso oldaddr; int s = splimp(), error, nsellength; oldaddr = ia->ia_addr; ia->ia_addr = *siso; /* * Give the interface a chance to initialize * if this is its first address, * and to validate the address if necessary. */ if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) { splx(s); ia->ia_addr = oldaddr; return (error); } if (scrub) { ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; iso_ifscrub(ifp, ia); ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; } /* XXX -- The following is here temporarily out of laziness in not changing every ethernet driver's if_ioctl routine */ if (ifp->if_output == ether_output) { ia->ia_ifa.ifa_rtrequest = llc_rtrequest; ia->ia_ifa.ifa_flags |= RTF_CLONING; } /* * Add route for the network. */ nsellength = ia->ia_addr.siso_tlen; ia->ia_addr.siso_tlen = 0; if (ifp->if_flags & IFF_LOOPBACK) { ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); } else if (ifp->if_flags & IFF_POINTOPOINT && ia->ia_dstaddr.siso_family == AF_ISO) error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); else { rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr, ia->ia_ifa.ifa_netmask); ia->ia_dstaddr.siso_nlen = min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6)); error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP); } ia->ia_addr.siso_tlen = nsellength; ia->ia_flags |= IFA_ROUTE; splx(s); return (error);}#ifdef notdefstruct ifaddr *iso_ifwithidi(addr) register struct sockaddr *addr;{ register struct ifnet *ifp; register struct ifaddr *ifa; register u_int af = addr->sa_family; if (af != AF_ISO) return (0); IFDEBUG(D_ROUTE) printf(">>> iso_ifwithidi addr\n"); dump_isoaddr( (struct sockaddr_iso *)(addr)); printf("\n"); ENDDEBUG for (ifp = ifnet; ifp; ifp = ifp->if_next) { IFDEBUG(D_ROUTE) printf("iso_ifwithidi ifnet %s\n", ifp->if_name); ENDDEBUG for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { IFDEBUG(D_ROUTE) printf("iso_ifwithidi address "); dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr)); ENDDEBUG if (ifa->ifa_addr->sa_family != addr->sa_family) continue;#define IFA_SIS(ifa)\ ((struct sockaddr_iso *)((ifa)->ifa_addr)) IFDEBUG(D_ROUTE) printf(" af same, args to iso_eqtype:\n"); printf("0x%x ", IFA_SIS(ifa)->siso_addr); printf(" 0x%x\n", &(((struct sockaddr_iso *)addr)->siso_addr)); ENDDEBUG if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr), &(((struct sockaddr_iso *)addr)->siso_addr))) { IFDEBUG(D_ROUTE) printf("ifa_ifwithidi: ifa found\n"); ENDDEBUG return (ifa); } IFDEBUG(D_ROUTE) printf(" iso_eqtype failed\n"); ENDDEBUG } } return ((struct ifaddr *)0);}#endif /* notdef *//* * FUNCTION: iso_ck_addr * * PURPOSE: return true if the iso_addr passed is * within the legal size limit for an iso address. * * RETURNS: true or false * * SIDE EFFECTS: * */iso_ck_addr(isoa)struct iso_addr *isoa; /* address to check */{ return (isoa->isoa_len <= 20);}#ifdef notdef/* * FUNCTION: iso_eqtype * * PURPOSE: Determine if two iso addresses are of the same type. * This is flaky. Really we should consider all type 47 addrs to be the * same - but there do exist different structures for 47 addrs. * Gosip adds a 3rd. * * RETURNS: true if the addresses are the same type * * SIDE EFFECTS: * * NOTES: By type, I mean rfc986, t37, or osinet * * This will first compare afis. If they match, then * if the addr is not t37, the idis must be compared. */iso_eqtype(isoaa, isoab)struct iso_addr *isoaa; /* first addr to check */struct iso_addr *isoab; /* other addr to check */{ if (isoaa->isoa_afi == isoab->isoa_afi) { if (isoaa->isoa_afi == AFI_37) return(1); else return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2)); } return(0);}#endif /* notdef *//* * FUNCTION: iso_localifa() * * PURPOSE: Find an interface addresss having a given destination * or at least matching the net. * * RETURNS: ptr to an interface address * * SIDE EFFECTS: * * NOTES: */struct iso_ifaddr *iso_localifa(siso) register struct sockaddr_iso *siso;{ register struct iso_ifaddr *ia; register char *cp1, *cp2, *cp3; register struct ifnet *ifp; struct iso_ifaddr *ia_maybe = 0; /* * We make one pass looking for both net matches and an exact * dst addr. */ for (ia = iso_ifaddr; ia; ia = ia->ia_next) { if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0)) continue; if (ifp->if_flags & IFF_POINTOPOINT) { if ((ia->ia_dstaddr.siso_family == AF_ISO) && SAME_ISOADDR(&ia->ia_dstaddr, siso)) return (ia); else if (SAME_ISOADDR(&ia->ia_addr, siso)) ia_maybe = ia; continue; } if (ia->ia_sockmask.siso_len) { char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask; cp1 = ia->ia_sockmask.siso_data; cp2 = siso->siso_data; cp3 = ia->ia_addr.siso_data; while (cp1 < cplim) if (*cp1++ & (*cp2++ ^ *cp3++)) goto next; ia_maybe = ia; } if (SAME_ISOADDR(&ia->ia_addr, siso)) return ia; next:; } return ia_maybe;}#ifdef TPCONS#include <netiso/cons.h>#endif /* TPCONS *//* * FUNCTION: iso_nlctloutput * * PURPOSE: Set options at the network level * * RETURNS: E* * * SIDE EFFECTS: * * NOTES: This could embody some of the functions of * rclnp_ctloutput and cons_ctloutput. */iso_nlctloutput(cmd, optname, pcb, m)int cmd; /* command:set or get */int optname; /* option of interest */caddr_t pcb; /* nl pcb */struct mbuf *m; /* data for set, buffer for get */{ struct isopcb *isop = (struct isopcb *)pcb; int error = 0; /* return value */ caddr_t data; /* data for option */ int data_len; /* data's length */ IFDEBUG(D_ISO) printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n", cmd, optname, pcb, m); ENDDEBUG if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT)) return(EOPNOTSUPP); data = mtod(m, caddr_t); data_len = (m)->m_len; IFDEBUG(D_ISO) printf("iso_nlctloutput: data is:\n"); dump_buf(data, data_len); ENDDEBUG switch (optname) {#ifdef TPCONS case CONSOPT_X25CRUD: if (cmd == PRCO_GETOPT) { error = EOPNOTSUPP; break; } if (data_len > MAXX25CRUDLEN) { error = EINVAL; break; } IFDEBUG(D_ISO) printf("iso_nlctloutput: setting x25 crud\n"); ENDDEBUG bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len); isop->isop_x25crud_len = data_len; break;#endif /* TPCONS */ default: error = EOPNOTSUPP; } if (cmd == PRCO_SETOPT) m_freem(m); return error;}#endif /* ISO */#ifdef ARGO_DEBUG/* * FUNCTION: dump_isoaddr * * PURPOSE: debugging * * RETURNS: nada * */dump_isoaddr(s) struct sockaddr_iso *s;{ char *clnp_saddr_isop(); register int i; if( s->siso_family == AF_ISO) { printf("ISO address: suffixlen %d, %s\n", s->siso_tlen, clnp_saddr_isop(s)); } else if( s->siso_family == AF_INET) { /* hack */ struct sockaddr_in *sin = (struct sockaddr_in *)s; printf("%d.%d.%d.%d: %d", (sin->sin_addr.s_addr>>24)&0xff, (sin->sin_addr.s_addr>>16)&0xff, (sin->sin_addr.s_addr>>8)&0xff, (sin->sin_addr.s_addr)&0xff, sin->sin_port); }}#endif /* ARGO_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -