1*5712Ssam /* if_imphost.c 4.1 82/02/06 */ 2*5712Ssam 3*5712Ssam #include "imp.h" 4*5712Ssam #if NIMP > 0 5*5712Ssam /* 6*5712Ssam * Host table manipulation routines. 7*5712Ssam * Only needed when shipping stuff through an IMP. 8*5712Ssam */ 9*5712Ssam 10*5712Ssam #include "../h/param.h" 11*5712Ssam #include "../h/mbuf.h" 12*5712Ssam #include "../net/in.h" 13*5712Ssam #include "../net/in_systm.h" 14*5712Ssam #include "../net/host.h" 15*5712Ssam #include "../net/if_imp.h" 16*5712Ssam 17*5712Ssam /* 18*5712Ssam * Head of host table hash chains. 19*5712Ssam */ 20*5712Ssam struct mbuf hosttable = { 0, MMINOFF }; 21*5712Ssam 22*5712Ssam /* 23*5712Ssam * Given an internet address 24*5712Ssam * return a host structure (if it exists). 25*5712Ssam */ 26*5712Ssam struct host * 27*5712Ssam h_lookup(addr) 28*5712Ssam struct in_addr addr; 29*5712Ssam { 30*5712Ssam register struct host *hp; 31*5712Ssam register struct mbuf *m; 32*5712Ssam register int hash = HOSTHASH(addr); 33*5712Ssam 34*5712Ssam COUNT(H_LOOKUP); 35*5712Ssam printf("h_lookup(%x)\n", addr); 36*5712Ssam for (m = &hosttable; m; m = m->m_next) { 37*5712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 38*5712Ssam if (hp->h_refcnt == 0) 39*5712Ssam break; 40*5712Ssam printf("h_lookup: addr=%x\n", hp->h_addr.s_addr); 41*5712Ssam if (hp->h_addr.s_addr == addr.s_addr) 42*5712Ssam return (hp); 43*5712Ssam } 44*5712Ssam return (0); 45*5712Ssam } 46*5712Ssam 47*5712Ssam /* 48*5712Ssam * Enter a reference to this host's internet 49*5712Ssam * address. If no host structure exists, create 50*5712Ssam * one and hook it into the host database. 51*5712Ssam */ 52*5712Ssam struct host * 53*5712Ssam h_enter(addr) 54*5712Ssam struct in_addr addr; 55*5712Ssam { 56*5712Ssam register struct mbuf *m, *mprev; 57*5712Ssam register struct host *hp; 58*5712Ssam register int hash = HOSTHASH(addr); 59*5712Ssam 60*5712Ssam COUNT(H_ENTER); 61*5712Ssam printf("h_enter(%x)\n", addr); 62*5712Ssam for (m = &hosttable; m; mprev = m, m = m->m_next) { 63*5712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 64*5712Ssam if (hp->h_refcnt == 0) 65*5712Ssam break; 66*5712Ssam printf("h_enter: addr=%x\n", addr); 67*5712Ssam if (hp->h_addr.s_addr == addr.s_addr) 68*5712Ssam goto foundhost; 69*5712Ssam } 70*5712Ssam 71*5712Ssam /* 72*5712Ssam * No current host structure, make one. 73*5712Ssam * If our search ran off the end of the 74*5712Ssam * chain of mbuf's, allocate another. 75*5712Ssam */ 76*5712Ssam printf("h_enter: new host\n"); 77*5712Ssam if (m == 0) { 78*5712Ssam m = m_getclr(M_DONTWAIT); 79*5712Ssam if (m == 0) 80*5712Ssam return (0); 81*5712Ssam mprev->m_next = m; 82*5712Ssam m->m_act = mprev; 83*5712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 84*5712Ssam } 85*5712Ssam mtod(m, struct hmbuf *)->hm_count++; 86*5712Ssam hp->h_addr = addr; 87*5712Ssam hp->h_status = HOSTS_UP; 88*5712Ssam 89*5712Ssam foundhost: 90*5712Ssam hp->h_refcnt++; /* know new structures have 0 val */ 91*5712Ssam return (hp); 92*5712Ssam } 93*5712Ssam 94*5712Ssam /* 95*5712Ssam * Free a reference to a host. If this causes the 96*5712Ssam * host structure to be released do so. 97*5712Ssam */ 98*5712Ssam h_free(addr) 99*5712Ssam struct in_addr addr; 100*5712Ssam { 101*5712Ssam register struct mbuf *m; 102*5712Ssam register struct host *hp; 103*5712Ssam register int hash = HOSTHASH(addr); 104*5712Ssam 105*5712Ssam COUNT(H_FREE); 106*5712Ssam printf("h_free(%x)\n", addr); 107*5712Ssam for (m = &hosttable; m; m = m->m_next) { 108*5712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 109*5712Ssam if (hp->h_refcnt == 0) 110*5712Ssam return; 111*5712Ssam if (hp->h_addr.s_addr == addr.s_addr) { 112*5712Ssam if (--hp->h_refcnt == 0) 113*5712Ssam h_release(mtod(m, struct hmbuf *), hp); 114*5712Ssam return; 115*5712Ssam } 116*5712Ssam } 117*5712Ssam panic("h_free"); 118*5712Ssam } 119*5712Ssam 120*5712Ssam /* 121*5712Ssam * Reset a given network's host entries. 122*5712Ssam * This involves clearing all packet queue's 123*5712Ssam * and releasing host structures. 124*5712Ssam */ 125*5712Ssam h_reset(net) 126*5712Ssam int net; 127*5712Ssam { 128*5712Ssam register struct mbuf *m; 129*5712Ssam register struct host *hp, *lp; 130*5712Ssam 131*5712Ssam COUNT(H_RESET); 132*5712Ssam printf("h_reset(%x)\n", net); 133*5712Ssam for (m = &hosttable; m; m = m->m_next) { 134*5712Ssam hp = mtod(m, struct hmbuf *)->hm_hosts; 135*5712Ssam lp = hp + HPMBUF; 136*5712Ssam while (hp < lp) { 137*5712Ssam if (hp->h_addr.s_net == net) 138*5712Ssam h_release(mtod(m, struct hmbuf *), hp); 139*5712Ssam hp++; 140*5712Ssam } 141*5712Ssam } 142*5712Ssam } 143*5712Ssam 144*5712Ssam /* 145*5712Ssam * Remove a host structure and release 146*5712Ssam * any resources it's accumulated. 147*5712Ssam */ 148*5712Ssam h_release(hm, hp) 149*5712Ssam struct hmbuf *hm; 150*5712Ssam register struct host *hp; 151*5712Ssam { 152*5712Ssam register struct mbuf *m; 153*5712Ssam 154*5712Ssam COUNT(H_RELEASE); 155*5712Ssam printf("h_release(%x,%x)\n", hm, hp); 156*5712Ssam /* 157*5712Ssam * Discard any packets left on the waiting q 158*5712Ssam */ 159*5712Ssam while (m = hp->h_q) { 160*5712Ssam hp->h_q = m->m_act; 161*5712Ssam m_freem(m); 162*5712Ssam } 163*5712Ssam /* 164*5712Ssam * We could compact the database here, but is 165*5712Ssam * it worth it? For now we assume not and just 166*5712Ssam * handle the simple case. 167*5712Ssam */ 168*5712Ssam printf("h_releasse: count=%d\n", hm->h_count); 169*5712Ssam if (--hm->hm_count || (m = dtom(hm)) == &hosttable) 170*5712Ssam return; 171*5712Ssam m->m_act->m_next = m->m_next; 172*5712Ssam m->m_next->m_act = m->m_act; 173*5712Ssam m_freem(m); 174*5712Ssam } 175