1 /* if_imphost.c 4.10 82/04/25 */ 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 99 foundhost: 100 hp->h_flags |= HF_INUSE; 101 splx(s); 102 return (hp); 103 } 104 105 /* 106 * Mark a host structure free and set it's 107 * timer going. 108 */ 109 hostfree(hp) 110 register struct host *hp; 111 { 112 int s = splnet(); 113 114 COUNT(HOSTFREE); 115 hp->h_flags &= ~HF_INUSE; 116 hp->h_timer = HOSTTIMER; 117 hp->h_rfnm = 0; 118 splx(s); 119 } 120 121 /* 122 * Reset a given network's host entries. 123 */ 124 hostreset(net) 125 int net; 126 { 127 register struct mbuf *m; 128 register struct host *hp, *lp; 129 struct hmbuf *hm; 130 int s = splnet(); 131 132 COUNT(HOSTRESET); 133 for (m = hosts; m; m = m->m_next) { 134 hm = mtod(m, struct hmbuf *); 135 hp = hm->hm_hosts; 136 lp = hp + HPMBUF; 137 while (hm->hm_count > 0 && hp < lp) { 138 if (hp->h_addr.s_net == net) { 139 hp->h_flags &= ~HF_INUSE; 140 hostrelease(hp); 141 } 142 hp++; 143 } 144 } 145 splx(s); 146 } 147 148 /* 149 * Remove a host structure and release 150 * any resources it's accumulated. 151 * This routine is always called at splnet. 152 */ 153 hostrelease(hp) 154 register struct host *hp; 155 { 156 register struct mbuf *m, **mprev, *mh = dtom(hp); 157 158 COUNT(HOSTRELEASE); 159 /* 160 * Discard any packets left on the waiting q 161 */ 162 if (m = hp->h_q) { 163 register struct mbuf *n; 164 165 do { 166 n = m->m_act; 167 m_freem(m); 168 m = n; 169 } while (m != hp->h_q); 170 hp->h_q = 0; 171 } 172 if (--mtod(mh, struct hmbuf *)->hm_count) 173 return; 174 mprev = &hosts; 175 while ((m = *mprev) != mh) 176 mprev = &m->m_next; 177 *mprev = m_free(mh); 178 } 179 180 /* 181 * Remove a packet from the holding q. 182 * The RFNM counter is also bumped. 183 */ 184 struct mbuf * 185 hostdeque(hp) 186 register struct host *hp; 187 { 188 register struct mbuf *m; 189 190 hp->h_rfnm--; 191 HOST_DEQUE(hp, m); 192 if (m) 193 return (m); 194 if (hp->h_rfnm == 0) 195 hostfree(hp); 196 return (0); 197 } 198 199 /* 200 * Host data base timer routine. 201 * Decrement timers on structures which are 202 * waiting to be deallocated. On expiration 203 * release resources, possibly deallocating 204 * mbuf associated with structure. 205 */ 206 hostslowtimo() 207 { 208 register struct mbuf *m; 209 register struct host *hp, *lp; 210 struct hmbuf *hm; 211 int s = splnet(); 212 213 COUNT(HOSTSLOWTIMO); 214 for (m = hosts; m; m = m->m_next) { 215 hm = mtod(m, struct hmbuf *); 216 hp = hm->hm_hosts; 217 lp = hp + HPMBUF; 218 while (hm->hm_count > 0 && hp < lp) { 219 if (hp->h_flags & HF_INUSE) 220 continue; 221 if (hp->h_timer && --hp->h_timer == 0) 222 hostrelease(hp); 223 hp++; 224 } 225 } 226 splx(s); 227 } 228