1*56483Ssklower /* 2*56483Ssklower * Copyright (c) 1980, 1986, 1991 Regents of the University of California. 3*56483Ssklower * All rights reserved. 4*56483Ssklower * 5*56483Ssklower * %sccs.include.redist.c% 6*56483Ssklower * 7*56483Ssklower * @(#)tuba_table.c 7.1 (Berkeley) 10/09/92 8*56483Ssklower */ 9*56483Ssklower #include "param.h" 10*56483Ssklower #include "systm.h" 11*56483Ssklower #include "proc.h" 12*56483Ssklower #include "mbuf.h" 13*56483Ssklower #include "socket.h" 14*56483Ssklower #include "socketvar.h" 15*56483Ssklower #include "domain.h" 16*56483Ssklower #include "protosw.h" 17*56483Ssklower #include "ioctl.h" 18*56483Ssklower 19*56483Ssklower #include "net/if.h" 20*56483Ssklower #include "net/af.h" 21*56483Ssklower #include "net/radix.h" 22*56483Ssklower 23*56483Ssklower #include "tuba_addr.h" 24*56483Ssklower 25*56483Ssklower #include "netiso/iso.h" 26*56483Ssklower 27*56483Ssklower #define SA(p) ((struct sockaddr *)(p)) 28*56483Ssklower 29*56483Ssklower int tuba_table_size; 30*56483Ssklower struct tuba_cache **tuba_table; 31*56483Ssklower struct radix_node_head *tuba_tree; 32*56483Ssklower extern int arpt_keep, arpt_prune; /* use same values as arp cache */ 33*56483Ssklower 34*56483Ssklower void 35*56483Ssklower tuba_timer() 36*56483Ssklower { 37*56483Ssklower int s = splnet(); 38*56483Ssklower int i; 39*56483Ssklower register struct tuba_cache **tc; 40*56483Ssklower long timelimit = time.tv_sec - arpt_keep; 41*56483Ssklower 42*56483Ssklower timeout(tuba_timer, (caddr_t)0, arpt_prune * hz); 43*56483Ssklower for (i = tuba_table_size; i > 0; i--) 44*56483Ssklower if ((tc = tuba_table[i]) && (tc->tc_refcnt == 0) && 45*56483Ssklower (tc->tc_time < timelimit)) { 46*56483Ssklower tuba_table[i] = 0; 47*56483Ssklower rn_delete((caddr_t)&tc->tc_addr, (caddr_t)0, tuba_tree); 48*56483Ssklower free((caddr_t)tc, M_RTABLE); 49*56483Ssklower } 50*56483Ssklower splx(s); 51*56483Ssklower } 52*56483Ssklower 53*56483Ssklower tuba_init() 54*56483Ssklower { 55*56483Ssklower rn_inithead((void **)&tuba_tree, 40); 56*56483Ssklower timeout(tuba_timer, (caddr_t)0, arpt_prune * hz); 57*56483Ssklower } 58*56483Ssklower 59*56483Ssklower int 60*56483Ssklower tuba_lookup(isoa, flags, wait) 61*56483Ssklower register struct iso_addr *isoa; 62*56483Ssklower int flags; 63*56483Ssklower { 64*56483Ssklower struct radix_node *rn; 65*56483Ssklower register struct tuba_cache *tc; 66*56483Ssklower int dupentry = 0, sum_even = 0, sum_odd = 0, delta, i; 67*56483Ssklower 68*56483Ssklower if (rn = rn_match(tuba_tree, (caddr_t)isoa)) { 69*56483Ssklower tc = (struct tuba_cache *)rn; 70*56483Ssklower tc->tc_time = time.tv_sec; 71*56483Ssklower return (tc->tc_index); 72*56483Ssklower } 73*56483Ssklower if ((tc = (struct tuba_cache *)malloc(sizeof(*tc), M_RTABLE, wait)) 74*56483Ssklower == NULL) 75*56483Ssklower return (0); 76*56483Ssklower bzero((caddr_t)tc, sizeof (*tc)) 77*56483Ssklower bcopy((caddr_t)isoa, (caddr_t)&tc->tc_addr, 1 + isoa->isoa_len); 78*56483Ssklower rn_insert((caddr_t)&tc->tc_addr, tuba_tree, &dupentry, tc->tc_nodes); 79*56483Ssklower if (dupentry) 80*56483Ssklower panic("tuba_lookup 1"); 81*56483Ssklower tc->tc_time = time.tv_sec; 82*56483Ssklower tc->tc_flags = flags; 83*56483Ssklower sum_even = isoa->isoa_len; 84*56483Ssklower for (i = sum_even; --i >= 0; ) { 85*56483Ssklower delta = isoa->isoa_genaddr[i]; 86*56483Ssklower i & 1 ? sum_even += delta : sum_odd += delta; 87*56483Ssklower } 88*56483Ssklower ICKSUM(tc->tc_sum_in, (sum_even << 8) + sum_odd); 89*56483Ssklower ICKSUM(tc->tc_sum_out, tc->sum_in + 0x1fffe - tc->tc_index); 90*56483Ssklower for (i = tuba_table_size; i > 0; i--) 91*56483Ssklower if (tuba_table[i] == 0) 92*56483Ssklower break; 93*56483Ssklower if (i) { 94*56483Ssklower tc->tc_index = 1; 95*56483Ssklower tuba_table[i] = tc; 96*56483Ssklower return (i); 97*56483Ssklower } 98*56483Ssklower if (tuba_table_size == 0) 99*56483Ssklower tuba_table_size = 15; 100*56483Ssklower if (tuba_table_size > 0x7fff) 101*56483Ssklower return (0); 102*56483Ssklower tuba_table_size = 1 + 2 * tuba_table_size; 103*56483Ssklower i = (tuba_table_size + 1) * sizeof(tc); 104*56483Ssklower new = (struct tuba_cache **)malloc((unsigned)i, M_RTABLE, wait); 105*56483Ssklower if (new == 0) { 106*56483Ssklower tuba_table_size = old_size; 107*56483Ssklower rn_delete((caddr_t)&tc->tc_addr, (caddr_t)0, tuba_tree); 108*56483Ssklower free((caddr_t)tc, M_RTABLE); 109*56483Ssklower return (0); 110*56483Ssklower } 111*56483Ssklower bzero((caddr_t)new, (unsigned)i); 112*56483Ssklower if (tuba_table) 113*56483Ssklower bcopy((caddr_t)tuba_table, (caddr_t)new, i >> 1); 114*56483Ssklower tuba_table[tc->tc_index = tuba_table_size] = tc; 115*56483Ssklower return (tc->tc_index); 116*56483Ssklower } 117