1 /* 2 * Copyright (c) 1982 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)if_imphost.c 6.4 (Berkeley) 06/08/85 7 */ 8 9 #include "imp.h" 10 #if NIMP > 0 11 /* 12 * Host table manipulation routines. 13 * Only needed when shipping stuff through an IMP. 14 * 15 * Everything in here is called at splimp from 16 * from the IMP protocol code (if_imp.c), or 17 * interlocks with the code at splimp. 18 */ 19 #include "param.h" 20 #include "mbuf.h" 21 22 #include "../netinet/in.h" 23 #include "../netinet/in_systm.h" 24 25 #include "if_imp.h" 26 #include "if_imphost.h" 27 28 /* 29 * Head of host table hash chains. 30 */ 31 struct mbuf *hosts; 32 33 /* 34 * Given an internet address 35 * return a host structure (if it exists). 36 */ 37 struct host * 38 hostlookup(addr) 39 struct in_addr addr; 40 { 41 register struct host *hp; 42 register struct mbuf *m; 43 register int hash = HOSTHASH(addr); 44 45 for (m = hosts; m; m = m->m_next) { 46 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 47 if (hp->h_addr.s_addr == addr.s_addr) { 48 hp->h_flags |= HF_INUSE; 49 return (hp); 50 } 51 } 52 return ((struct host *)0); 53 } 54 55 /* 56 * Enter a reference to this host's internet 57 * address. If no host structure exists, create 58 * one and hook it into the host database. 59 */ 60 struct host * 61 hostenter(addr) 62 struct in_addr addr; 63 { 64 register struct mbuf *m, **mprev; 65 register struct host *hp, *hp0 = 0; 66 register int hash = HOSTHASH(addr); 67 68 mprev = &hosts; 69 while (m = *mprev) { 70 mprev = &m->m_next; 71 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 72 if ((hp->h_flags & HF_INUSE) == 0) { 73 if (hp->h_addr.s_addr == addr.s_addr) 74 goto foundhost; 75 if (hp0 == 0) 76 hp0 = hp; 77 continue; 78 } 79 if (hp->h_addr.s_addr == addr.s_addr) 80 goto foundhost; 81 } 82 83 /* 84 * No current host structure, make one. 85 * If our search ran off the end of the 86 * chain of mbuf's, allocate another. 87 */ 88 if (hp0 == 0) { 89 m = m_getclr(M_DONTWAIT, MT_HTABLE); 90 if (m == NULL) 91 return ((struct host *)0); 92 *mprev = m; 93 hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 94 } 95 mtod(dtom(hp0), struct hmbuf *)->hm_count++; 96 hp = hp0; 97 hp->h_addr = addr; 98 hp->h_timer = 0; 99 hp->h_flags = 0; 100 101 foundhost: 102 hp->h_flags |= HF_INUSE; 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 114 hp->h_flags &= ~HF_INUSE; 115 hp->h_timer = HOSTTIMER; 116 hp->h_rfnm = 0; 117 } 118 119 /* 120 * Reset a given network's host entries. 121 */ 122 hostreset(net) 123 long net; 124 { 125 register struct mbuf *m; 126 register struct host *hp, *lp; 127 struct hmbuf *hm; 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 (in_netof(hp->h_addr) == net) { 135 hp->h_flags &= ~HF_INUSE; 136 hostrelease(hp); 137 } 138 hp++; 139 } 140 } 141 } 142 143 /* 144 * Remove a host structure and release 145 * any resources it's accumulated. 146 */ 147 hostrelease(hp) 148 register struct host *hp; 149 { 150 register struct mbuf *m, **mprev, *mh = dtom(hp); 151 152 /* 153 * Discard any packets left on the waiting q 154 */ 155 if (m = hp->h_q) { 156 register struct mbuf *n; 157 158 do { 159 n = m->m_act; 160 m_freem(m); 161 m = n; 162 } while (m != hp->h_q); 163 hp->h_q = 0; 164 } 165 hp->h_flags = 0; 166 hp->h_rfnm = 0; 167 if (--mtod(mh, struct hmbuf *)->hm_count) 168 return; 169 mprev = &hosts; 170 while ((m = *mprev) != mh) 171 mprev = &m->m_next; 172 *mprev = m_free(mh); 173 } 174 175 /* 176 * Remove a packet from the holding q. 177 * The RFNM counter is also bumped. 178 */ 179 struct mbuf * 180 hostdeque(hp) 181 register struct host *hp; 182 { 183 register struct mbuf *m; 184 185 hp->h_rfnm--; 186 HOST_DEQUE(hp, m); 187 if (m) 188 return (m); 189 if (hp->h_rfnm == 0) 190 hostfree(hp); 191 return (0); 192 } 193 194 /* 195 * Host data base timer routine. 196 * Decrement timers on structures which are 197 * waiting to be deallocated. On expiration 198 * release resources, possibly deallocating 199 * mbuf associated with structure. 200 */ 201 hostslowtimo() 202 { 203 register struct mbuf *m; 204 register struct host *hp, *lp; 205 struct hmbuf *hm; 206 int s = splimp(); 207 208 for (m = hosts; m; m = m->m_next) { 209 hm = mtod(m, struct hmbuf *); 210 hp = hm->hm_hosts; 211 lp = hp + HPMBUF; 212 for (; hm->hm_count > 0 && hp < lp; hp++) { 213 if (hp->h_flags & HF_INUSE) 214 continue; 215 if (hp->h_timer && --hp->h_timer == 0) 216 hostrelease(hp); 217 } 218 } 219 splx(s); 220 } 221 #endif 222