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