1 /* 2 * Copyright (c) 1982, 1986 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 7.2 (Berkeley) 02/03/88 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 #include "socket.h" 22 #include "syslog.h" 23 24 #include "../net/if.h" 25 26 #include "../netinet/in.h" 27 #include "../netinet/in_systm.h" 28 29 #include "if_imp.h" 30 #include "if_imphost.h" 31 32 /* 33 * Head of host table hash chains. 34 */ 35 struct mbuf *hosts; 36 extern struct imp_softc imp_softc[]; 37 38 /* 39 * Given an internet address 40 * return a host structure (if it exists). 41 */ 42 struct host * 43 hostlookup(imp, host, unit) 44 int imp, host, unit; 45 { 46 register struct host *hp; 47 register struct mbuf *m; 48 register int hash = HOSTHASH(imp, host); 49 50 for (m = hosts; m; m = m->m_next) { 51 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 52 if (hp->h_imp == imp && hp->h_host == host && 53 hp->h_unit == unit) { 54 hp->h_flags |= HF_INUSE; 55 return (hp); 56 } 57 } 58 return ((struct host *)0); 59 } 60 61 /* 62 * Enter a reference to this host's internet 63 * address. If no host structure exists, create 64 * one and hook it into the host database. 65 */ 66 struct host * 67 hostenter(imp, host, unit) 68 int imp, host, unit; 69 { 70 register struct mbuf *m, **mprev; 71 register struct host *hp, *hp0 = 0; 72 register int hash = HOSTHASH(imp, host); 73 74 mprev = &hosts; 75 while (m = *mprev) { 76 mprev = &m->m_next; 77 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 78 if (hp->h_imp == imp && hp->h_host == host && 79 hp->h_unit == unit) 80 goto foundhost; 81 if ((hp->h_flags & HF_INUSE) == 0) { 82 if (hp0 == 0) 83 hp0 = hp; 84 continue; 85 } 86 } 87 88 /* 89 * No current host structure, make one. 90 * If our search ran off the end of the 91 * chain of mbuf's, allocate another. 92 */ 93 if (hp0 == 0) { 94 m = m_getclr(M_DONTWAIT, MT_HTABLE); 95 if (m == NULL) 96 return ((struct host *)0); 97 *mprev = m; 98 hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 99 } 100 mtod(dtom(hp0), struct hmbuf *)->hm_count++; 101 hp = hp0; 102 hp->h_imp = imp; 103 hp->h_host = host; 104 hp->h_unit = unit; 105 hp->h_timer = 0; 106 hp->h_flags = 0; 107 108 foundhost: 109 hp->h_flags |= HF_INUSE; 110 return (hp); 111 } 112 113 /* 114 * Reset a given imp unit's host entries. 115 */ 116 hostreset(unit) 117 int unit; 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 (hp->h_unit == unit) 129 hostrelease(hp); 130 hp++; 131 } 132 } 133 hostcompress(); 134 } 135 136 /* 137 * Remove a host structure and release 138 * any resources it's accumulated. 139 */ 140 hostrelease(hp) 141 register struct host *hp; 142 { 143 register struct mbuf *m, **mprev, *mh = dtom(hp); 144 145 /* 146 * Discard any packets left on the waiting q 147 */ 148 if (m = hp->h_q) { 149 register struct mbuf *n; 150 151 do { 152 n = m->m_act; 153 m_freem(m); 154 m = n; 155 } while (m != hp->h_q); 156 hp->h_q = 0; 157 } 158 hp->h_flags = 0; 159 hp->h_rfnm = 0; 160 --mtod(mh, struct hmbuf *)->hm_count; 161 } 162 163 hostcompress() 164 { 165 register struct mbuf *m, **mprev; 166 167 mprev = &hosts; 168 while (m = *mprev) { 169 if (mtod(m, struct hmbuf *)->hm_count == 0) 170 *mprev = m_free(m); 171 else 172 mprev = &m->m_next; 173 } 174 } 175 176 /* 177 * Host data base timer routine. 178 * Decrement timers on structures which are 179 * waiting to be deallocated. On expiration 180 * release resources, possibly deallocating 181 * mbuf associated with structure. 182 */ 183 hostslowtimo() 184 { 185 register struct mbuf *m; 186 register struct host *hp, *lp; 187 struct hmbuf *hm; 188 int s = splimp(), any = 0; 189 190 for (m = hosts; m; m = m->m_next) { 191 hm = mtod(m, struct hmbuf *); 192 hp = hm->hm_hosts; 193 lp = hp + HPMBUF; 194 for (; hm->hm_count > 0 && hp < lp; hp++) { 195 if (hp->h_timer && --hp->h_timer == 0) { 196 if (hp->h_rfnm) { 197 log(LOG_WARNING, 198 "imp%d: host %d/imp %d, lost %d rfnms\n", 199 hp->h_unit, hp->h_host, ntohs(hp->h_imp), 200 hp->h_rfnm); 201 imp_softc[hp->h_unit].imp_lostrfnm += hp->h_rfnm; 202 hp->h_rfnm = 0; 203 if (hp->h_q) { 204 imprestarthost(hp); 205 continue; 206 } 207 } 208 any = 1; 209 hostrelease(hp); 210 } 211 } 212 } 213 if (any) 214 hostcompress(); 215 splx(s); 216 } 217 #endif 218