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