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