📄 clnp_subr.c
字号:
* If options are present, update them */ if (oidx) { struct iso_addr *mysrc = &ia->ia_addr.siso_addr; if (mysrc == NULL) { clnp_discard(m, ADDR_DESTUNREACH); INCSTAT(cns_cantforward); clnp_stat.cns_forward--; goto done; } else { (void) clnp_dooptions(m, oidx, ifp, mysrc); } }#ifdef DECBIT if (ifp->if_snd.ifq_len > congest_threshold) { /* * Congestion! Set the Dec Bit and thank Dave Oran */ IFDEBUG(D_FORWARD) printf("clnp_forward: congestion experienced\n"); ENDDEBUG if ((oidx) && (oidx->cni_qos_formatp)) { caddr_t qosp = CLNP_OFFTOOPT(m, oidx->cni_qos_formatp); u_char qos = *qosp; IFDEBUG(D_FORWARD) printf("clnp_forward: setting congestion bit (qos x%x)\n", qos); ENDDEBUG if ((qos & CLNPOVAL_GLOBAL) == CLNPOVAL_GLOBAL) { qos |= CLNPOVAL_CONGESTED; INCSTAT(cns_congest_set); *qosp = qos; } } }#endif /* DECBIT */ /* * Dispatch the datagram if it is small enough, otherwise fragment */ if (len <= SN_MTU(ifp, route.ro_rt)) { iso_gen_csum(m, CLNP_CKSUM_OFF, (int)clnp->cnf_hdr_len); (void) (*ifp->if_output)(ifp, m, next_hop, route.ro_rt); } else { (void) clnp_fragment(ifp, m, next_hop, len, seg_off, /* flags */0, route.ro_rt); } done: /* * Free route */ if (route.ro_rt != NULL) { RTFREE(route.ro_rt); }}#ifdef notdef/* * FUNCTION: clnp_insert_addr * * PURPOSE: Insert the address part into a clnp datagram. * * RETURNS: Address of first byte after address part in datagram. * * SIDE EFFECTS: * * NOTES: Assume that there is enough space for the address part. */caddr_tclnp_insert_addr(bufp, srcp, dstp)caddr_t bufp; /* address of where addr part goes */register struct iso_addr *srcp; /* ptr to src addr */register struct iso_addr *dstp; /* ptr to dst addr */{ *bufp++ = dstp->isoa_len; (void) bcopy((caddr_t)dstp, bufp, dstp->isoa_len); bufp += dstp->isoa_len; *bufp++ = srcp->isoa_len; (void) bcopy((caddr_t)srcp, bufp, srcp->isoa_len); bufp += srcp->isoa_len; return bufp;}#endif /* notdef *//* * FUNCTION: clnp_route * * PURPOSE: Route a clnp datagram to the first hop toward its * destination. In many cases, the first hop will be * the destination. The address of a route * is specified. If a routing entry is present in * that route, and it is still up to the same destination, * then no further action is necessary. Otherwise, a * new routing entry will be allocated. * * RETURNS: route found - 0 * unix error code * * SIDE EFFECTS: * * NOTES: It is up to the caller to free the routing entry * allocated in route. */clnp_route(dst, ro, flags, first_hop, ifa) struct iso_addr *dst; /* ptr to datagram destination */ register struct route_iso *ro; /* existing route structure */ int flags; /* flags for routing */ struct sockaddr **first_hop; /* result: fill in with ptr to firsthop */ struct iso_ifaddr **ifa; /* result: fill in with ptr to interface */{ if (flags & SO_DONTROUTE) { struct iso_ifaddr *ia; if (ro->ro_rt) { RTFREE(ro->ro_rt); ro->ro_rt = 0; } bzero((caddr_t)&ro->ro_dst, sizeof(ro->ro_dst)); bcopy((caddr_t)dst, (caddr_t)&ro->ro_dst.siso_addr, 1 + (unsigned)dst->isoa_len); ro->ro_dst.siso_family = AF_ISO; ro->ro_dst.siso_len = sizeof(ro->ro_dst); ia = iso_localifa(&ro->ro_dst); if (ia == 0) return EADDRNOTAVAIL; if (ifa) *ifa = ia; if (first_hop) *first_hop = (struct sockaddr *)&ro->ro_dst; return 0; } /* * If there is a cached route, check that it is still up and to * the same destination. If not, free it and try again. */ if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || (Bcmp(ro->ro_dst.siso_data, dst->isoa_genaddr, dst->isoa_len)))) { IFDEBUG(D_ROUTE) printf("clnp_route: freeing old route: ro->ro_rt 0x%x\n", ro->ro_rt); printf("clnp_route: old route refcnt: 0x%x\n", ro->ro_rt->rt_refcnt); ENDDEBUG /* free old route entry */ RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)0; } else { IFDEBUG(D_ROUTE) printf("clnp_route: OK route exists\n"); ENDDEBUG } if (ro->ro_rt == 0) { /* set up new route structure */ bzero((caddr_t)&ro->ro_dst, sizeof(ro->ro_dst)); ro->ro_dst.siso_len = sizeof(ro->ro_dst); ro->ro_dst.siso_family = AF_ISO; Bcopy(dst, &ro->ro_dst.siso_addr, 1 + dst->isoa_len); /* allocate new route */ IFDEBUG(D_ROUTE) printf("clnp_route: allocating new route to %s\n", clnp_iso_addrp(dst)); ENDDEBUG rtalloc((struct route *)ro); } if (ro->ro_rt == 0) return(ENETUNREACH); /* rtalloc failed */ ro->ro_rt->rt_use++; if (ifa) if ((*ifa = (struct iso_ifaddr *)ro->ro_rt->rt_ifa) == 0) panic("clnp_route"); if (first_hop) { if (ro->ro_rt->rt_flags & RTF_GATEWAY) *first_hop = ro->ro_rt->rt_gateway; else *first_hop = (struct sockaddr *)&ro->ro_dst; } return(0);}/* * FUNCTION: clnp_srcroute * * PURPOSE: Source route the datagram. If complete source * routing is specified but not possible, then * return an error. If src routing is terminated, then * try routing on destination. * Usage of first_hop, * ifp, and error return is identical to clnp_route. * * RETURNS: 0 or unix error code * * SIDE EFFECTS: * * NOTES: Remember that option index pointers are really * offsets from the beginning of the mbuf. */clnp_srcroute(options, oidx, ro, first_hop, ifa, final_dst)struct mbuf *options; /* ptr to options */struct clnp_optidx *oidx; /* index to options */struct route_iso *ro; /* route structure */struct sockaddr **first_hop; /* RETURN: fill in with ptr to firsthop */struct iso_ifaddr **ifa; /* RETURN: fill in with ptr to interface */struct iso_addr *final_dst; /* final destination */{ struct iso_addr dst; /* first hop specified by src rt */ int error = 0; /* return code */ /* * Check if we have run out of routes * If so, then try to route on destination. */ if CLNPSRCRT_TERM(oidx, options) { dst.isoa_len = final_dst->isoa_len; bcopy(final_dst->isoa_genaddr, dst.isoa_genaddr, dst.isoa_len); } else { /* * setup dst based on src rt specified */ dst.isoa_len = CLNPSRCRT_CLEN(oidx, options); bcopy(CLNPSRCRT_CADDR(oidx, options), dst.isoa_genaddr, dst.isoa_len); } /* * try to route it */ error = clnp_route(&dst, ro, 0, first_hop, ifa); if (error != 0) return error; /* * If complete src rt, first hop must be equal to dst */ if ((CLNPSRCRT_TYPE(oidx, options) == CLNPOVAL_COMPRT) && (!iso_addrmatch1(&(*(struct sockaddr_iso **)first_hop)->siso_addr,&dst))){ IFDEBUG(D_OPTIONS) printf("clnp_srcroute: complete src route failed\n"); ENDDEBUG return EHOSTUNREACH; /* RAH? would like ESRCRTFAILED */ } return error;}/* * FUNCTION: clnp_echoreply * * PURPOSE: generate an echo reply packet and transmit * * RETURNS: result of clnp_output * * SIDE EFFECTS: */clnp_echoreply(ec_m, ec_len, ec_src, ec_dst, ec_oidxp)struct mbuf *ec_m; /* echo request */int ec_len; /* length of ec */struct sockaddr_iso *ec_src; /* src of ec */struct sockaddr_iso *ec_dst; /* destination of ec (i.e., us) */struct clnp_optidx *ec_oidxp; /* options index to ec packet */{ struct isopcb isopcb; int flags = CLNP_NOCACHE|CLNP_ECHOR; int ret; /* fill in fake isopcb to pass to output function */ bzero(&isopcb, sizeof(isopcb)); isopcb.isop_laddr = ec_dst; isopcb.isop_faddr = ec_src; /* forget copying the options for now. If implemented, need only * copy record route option, but it must be reset to zero length */ ret = clnp_output(ec_m, &isopcb, ec_len, flags); IFDEBUG(D_OUTPUT) printf("clnp_echoreply: output returns %d\n", ret); ENDDEBUG return ret;}/* * FUNCTION: clnp_badmtu * * PURPOSE: print notice of route with mtu not initialized. * * RETURNS: mtu of ifp. * * SIDE EFFECTS: prints notice, slows down system. */clnp_badmtu(ifp, rt, line, file)struct ifnet *ifp; /* outgoing interface */struct rtentry *rt; /* dst route */int line; /* where the dirty deed occured */char *file; /* where the dirty deed occured */{ printf("sending on route 0x%x with no mtu, line %d of file %s\n", rt, line, file);#ifdef ARGO_DEBUG printf("route dst is "); dump_isoaddr(rt_key(rt));#endif return ifp->if_mtu;}/* * FUNCTION: clnp_ypocb - backwards bcopy * * PURPOSE: bcopy starting at end of src rather than beginning. * * RETURNS: none * * SIDE EFFECTS: * * NOTES: No attempt has been made to make this efficient */clnp_ypocb(from, to, len)caddr_t from; /* src buffer */caddr_t to; /* dst buffer */u_int len; /* number of bytes */{ while (len--) *(to + len) = *(from + len);}#endif /* ISO */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -