1 /* if_imphost.c 6.3 85/02/28 */ 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 * Everything in here is called at splimp from 10 * from the IMP protocol code (if_imp.c), or 11 * interlocks with the code at splimp. 12 */ 13 #include "param.h" 14 #include "mbuf.h" 15 16 #include "../netinet/in.h" 17 #include "../netinet/in_systm.h" 18 19 #include "if_imp.h" 20 #include "if_imphost.h" 21 22 /* 23 * Head of host table hash chains. 24 */ 25 struct mbuf *hosts; 26 27 /* 28 * Given an internet address 29 * return a host structure (if it exists). 30 */ 31 struct host * 32 hostlookup(addr) 33 struct in_addr addr; 34 { 35 register struct host *hp; 36 register struct mbuf *m; 37 register int hash = HOSTHASH(addr); 38 39 for (m = hosts; m; m = m->m_next) { 40 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 41 if (hp->h_addr.s_addr == addr.s_addr) { 42 hp->h_flags |= HF_INUSE; 43 return (hp); 44 } 45 } 46 return ((struct host *)0); 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 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 == NULL) 85 return ((struct host *)0); 86 *mprev = m; 87 hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 88 } 89 mtod(dtom(hp0), struct hmbuf *)->hm_count++; 90 hp = hp0; 91 hp->h_addr = addr; 92 hp->h_timer = 0; 93 hp->h_flags = 0; 94 95 foundhost: 96 hp->h_flags |= HF_INUSE; 97 return (hp); 98 } 99 100 /* 101 * Mark a host structure free and set it's 102 * timer going. 103 */ 104 hostfree(hp) 105 register struct host *hp; 106 { 107 108 hp->h_flags &= ~HF_INUSE; 109 hp->h_timer = HOSTTIMER; 110 hp->h_rfnm = 0; 111 } 112 113 /* 114 * Reset a given network's host entries. 115 */ 116 hostreset(net) 117 long net; 118 { 119 register struct mbuf *m; 120 register struct host *hp, *lp; 121 struct hmbuf *hm; 122 123 for (m = hosts; m; m = m->m_next) { 124 hm = mtod(m, struct hmbuf *); 125 hp = hm->hm_hosts; 126 lp = hp + HPMBUF; 127 while (hm->hm_count > 0 && hp < lp) { 128 if (in_netof(hp->h_addr) == net) { 129 hp->h_flags &= ~HF_INUSE; 130 hostrelease(hp); 131 } 132 hp++; 133 } 134 } 135 } 136 137 /* 138 * Remove a host structure and release 139 * any resources it's accumulated. 140 */ 141 hostrelease(hp) 142 register struct host *hp; 143 { 144 register struct mbuf *m, **mprev, *mh = dtom(hp); 145 146 /* 147 * Discard any packets left on the waiting q 148 */ 149 if (m = hp->h_q) { 150 register struct mbuf *n; 151 152 do { 153 n = m->m_act; 154 m_freem(m); 155 m = n; 156 } while (m != hp->h_q); 157 hp->h_q = 0; 158 } 159 hp->h_flags = 0; 160 hp->h_rfnm = 0; 161 if (--mtod(mh, struct hmbuf *)->hm_count) 162 return; 163 mprev = &hosts; 164 while ((m = *mprev) != mh) 165 mprev = &m->m_next; 166 *mprev = m_free(mh); 167 } 168 169 /* 170 * Remove a packet from the holding q. 171 * The RFNM counter is also bumped. 172 */ 173 struct mbuf * 174 hostdeque(hp) 175 register struct host *hp; 176 { 177 register struct mbuf *m; 178 179 hp->h_rfnm--; 180 HOST_DEQUE(hp, m); 181 if (m) 182 return (m); 183 if (hp->h_rfnm == 0) 184 hostfree(hp); 185 return (0); 186 } 187 188 /* 189 * Host data base timer routine. 190 * Decrement timers on structures which are 191 * waiting to be deallocated. On expiration 192 * release resources, possibly deallocating 193 * mbuf associated with structure. 194 */ 195 hostslowtimo() 196 { 197 register struct mbuf *m; 198 register struct host *hp, *lp; 199 struct hmbuf *hm; 200 int s = splimp(); 201 202 for (m = hosts; m; m = m->m_next) { 203 hm = mtod(m, struct hmbuf *); 204 hp = hm->hm_hosts; 205 lp = hp + HPMBUF; 206 for (; hm->hm_count > 0 && hp < lp; hp++) { 207 if (hp->h_flags & HF_INUSE) 208 continue; 209 if (hp->h_timer && --hp->h_timer == 0) 210 hostrelease(hp); 211 } 212 } 213 splx(s); 214 } 215 #endif 216