1 /* if_imphost.c 4.12 82/05/11 */ 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/if_imp.h" 15 #include "../net/if_imphost.h" 16 17 /* 18 * Head of host table hash chains. 19 */ 20 struct mbuf *hosts; 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 int s = splnet(); 34 35 COUNT(HOSTLOOKUP); 36 for (m = hosts; m; m = m->m_next) { 37 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 38 if (hp->h_addr.s_addr == addr.s_addr) { 39 hp->h_flags |= HF_INUSE; 40 goto found; 41 } 42 } 43 hp = 0; 44 found: 45 splx(s); 46 return (hp); 47 } 48 49 /* 50 * Enter a reference to this host's internet 51 * address. If no host structure exists, create 52 * one and hook it into the host database. 53 */ 54 struct host * 55 hostenter(addr) 56 struct in_addr addr; 57 { 58 register struct mbuf *m, **mprev; 59 register struct host *hp, *hp0 = 0; 60 register int hash = HOSTHASH(addr); 61 int s = splnet(); 62 63 COUNT(HOSTENTER); 64 mprev = &hosts; 65 while (m = *mprev) { 66 mprev = &m->m_next; 67 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 68 if ((hp->h_flags & HF_INUSE) == 0) { 69 if (hp->h_addr.s_addr == addr.s_addr) 70 goto foundhost; 71 if (hp0 == 0) 72 hp0 = hp; 73 continue; 74 } 75 if (hp->h_addr.s_addr == addr.s_addr) 76 goto foundhost; 77 } 78 79 /* 80 * No current host structure, make one. 81 * If our search ran off the end of the 82 * chain of mbuf's, allocate another. 83 */ 84 if (hp0 == 0) { 85 m = m_getclr(M_DONTWAIT); 86 if (m == 0) { 87 splx(s); 88 return (0); 89 } 90 *mprev = m; 91 m->m_off = MMINOFF; 92 hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 93 } 94 mtod(dtom(hp0), struct hmbuf *)->hm_count++; 95 hp = hp0; 96 hp->h_addr = addr; 97 hp->h_timer = 0; 98 hp->h_flags = 0; 99 100 foundhost: 101 hp->h_flags |= HF_INUSE; 102 splx(s); 103 return (hp); 104 } 105 106 /* 107 * Mark a host structure free and set it's 108 * timer going. 109 */ 110 hostfree(hp) 111 register struct host *hp; 112 { 113 int s = splnet(); 114 115 COUNT(HOSTFREE); 116 hp->h_flags &= ~HF_INUSE; 117 hp->h_timer = HOSTTIMER; 118 hp->h_rfnm = 0; 119 splx(s); 120 } 121 122 /* 123 * Reset a given network's host entries. 124 */ 125 hostreset(net) 126 int net; 127 { 128 register struct mbuf *m; 129 register struct host *hp, *lp; 130 struct hmbuf *hm; 131 int s = splnet(); 132 133 COUNT(HOSTRESET); 134 for (m = hosts; m; m = m->m_next) { 135 hm = mtod(m, struct hmbuf *); 136 hp = hm->hm_hosts; 137 lp = hp + HPMBUF; 138 while (hm->hm_count > 0 && hp < lp) { 139 if (hp->h_addr.s_net == net) { 140 hp->h_flags &= ~HF_INUSE; 141 hostrelease(hp); 142 } 143 hp++; 144 } 145 } 146 splx(s); 147 } 148 149 /* 150 * Remove a host structure and release 151 * any resources it's accumulated. 152 * This routine is always called at splnet. 153 */ 154 hostrelease(hp) 155 register struct host *hp; 156 { 157 register struct mbuf *m, **mprev, *mh = dtom(hp); 158 159 COUNT(HOSTRELEASE); 160 /* 161 * Discard any packets left on the waiting q 162 */ 163 if (m = hp->h_q) { 164 register struct mbuf *n; 165 166 do { 167 n = m->m_act; 168 m_freem(m); 169 m = n; 170 } while (m != hp->h_q); 171 hp->h_q = 0; 172 } 173 hp->h_flags = 0; 174 if (--mtod(mh, struct hmbuf *)->hm_count) 175 return; 176 mprev = &hosts; 177 while ((m = *mprev) != mh) 178 mprev = &m->m_next; 179 *mprev = m_free(mh); 180 } 181 182 /* 183 * Remove a packet from the holding q. 184 * The RFNM counter is also bumped. 185 */ 186 struct mbuf * 187 hostdeque(hp) 188 register struct host *hp; 189 { 190 register struct mbuf *m; 191 192 hp->h_rfnm--; 193 HOST_DEQUE(hp, m); 194 if (m) 195 return (m); 196 if (hp->h_rfnm == 0) 197 hostfree(hp); 198 return (0); 199 } 200 201 /* 202 * Host data base timer routine. 203 * Decrement timers on structures which are 204 * waiting to be deallocated. On expiration 205 * release resources, possibly deallocating 206 * mbuf associated with structure. 207 */ 208 hostslowtimo() 209 { 210 register struct mbuf *m; 211 register struct host *hp, *lp; 212 struct hmbuf *hm; 213 int s = splnet(); 214 215 COUNT(HOSTSLOWTIMO); 216 for (m = hosts; m; m = m->m_next) { 217 hm = mtod(m, struct hmbuf *); 218 hp = hm->hm_hosts; 219 lp = hp + HPMBUF; 220 for (; hm->hm_count > 0 && hp < lp; hp++) { 221 if (hp->h_flags & HF_INUSE) 222 continue; 223 if (hp->h_timer && --hp->h_timer == 0) 224 hostrelease(hp); 225 } 226 } 227 splx(s); 228 } 229