1 /*
2 * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
7 * @(#)if_imphost.c 7.11 (Berkeley) 10/11/92
8 */
9
10 #include "imp.h"
11 #if NIMP > 0
12 /*
13 * Host table manipulation routines.
14 * Only needed when shipping stuff through an IMP.
15 *
16 * Everything in here is called at splimp from
17 * from the IMP protocol code (if_imp.c), or
18 * interlocks with the code at splimp.
19 */
20 #include <sys/param.h>
21 #include <sys/mbuf.h>
22 #include <sys/socket.h>
23 #include <sys/syslog.h>
24
25 #include <net/if.h>
26
27 #include <netinet/in.h>
28 #include <netinet/in_systm.h>
29
30 #include <netimp/if_imp.h>
31 #include <netimp/if_imphost.h>
32
33 extern struct imp_softc imp_softc[];
34
35 /*
36 * Given an internet address
37 * return a host structure (if it exists).
38 */
39 struct host *
hostlookup(imp,host,unit)40 hostlookup(imp, host, unit)
41 int imp, host, unit;
42 {
43 register struct host *hp;
44 register struct mbuf *m;
45 register int hash = HOSTHASH(imp, host);
46
47 for (m = imp_softc[unit].imp_hosts; m; m = m->m_next) {
48 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
49 if (hp->h_imp == imp && hp->h_host == host) {
50 if ((hp->h_flags & HF_INUSE) == 0)
51 mtod(dtom(hp), struct hmbuf *)->hm_count++;
52 hp->h_flags |= HF_INUSE;
53 return (hp);
54 }
55 }
56 return ((struct host *)0);
57 }
58
59 /*
60 * Enter a reference to this host's internet
61 * address. If no host structure exists, create
62 * one and hook it into the host database.
63 */
64 struct host *
hostenter(imp,host,unit)65 hostenter(imp, host, unit)
66 int imp, host, unit;
67 {
68 register struct mbuf *m, **mprev;
69 register struct host *hp, *hp0 = 0;
70 register int hash = HOSTHASH(imp, host);
71
72 mprev = &imp_softc[unit].imp_hosts;
73 while (m = *mprev) {
74 mprev = &m->m_next;
75 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
76 if (hp->h_imp == imp && hp->h_host == host) {
77 if ((hp->h_flags & HF_INUSE) == 0)
78 mtod(dtom(hp), struct hmbuf *)->hm_count++;
79 goto foundhost;
80 }
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 hp = hp0;
101 mtod(dtom(hp), struct hmbuf *)->hm_count++;
102 hp->h_imp = imp;
103 hp->h_host = host;
104 hp->h_timer = 0;
105 hp->h_flags = 0;
106
107 foundhost:
108 hp->h_flags |= HF_INUSE;
109 return (hp);
110 }
111
112 /*
113 * Reset a given imp unit's host entries.
114 * Must be called at splimp.
115 */
hostreset(unit)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 = imp_softc[unit].imp_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 hostrelease(hp);
129 hp++;
130 }
131 }
132 hostcompress(unit);
133 }
134
135 /*
136 * Remove a host structure and release
137 * any resources it's accumulated.
138 */
hostrelease(hp)139 hostrelease(hp)
140 register struct host *hp;
141 {
142
143 if (hp->h_q)
144 hostflush(hp);
145 hp->h_rfnm = 0;
146 if (hp->h_flags & HF_INUSE)
147 --mtod(dtom(hp), struct hmbuf *)->hm_count;
148 hp->h_flags = 0;
149 }
150
151 /*
152 * Flush the message queue for a host.
153 */
hostflush(hp)154 hostflush(hp)
155 register struct host *hp;
156 {
157 register struct mbuf *m;
158
159 /*
160 * Discard any packets left on the waiting q
161 */
162 if (m = hp->h_q) {
163 register struct mbuf *n;
164
165 do {
166 n = m->m_act;
167 m_freem(m);
168 m = n;
169 } while (m != hp->h_q);
170 hp->h_q = 0;
171 hp->h_qcnt = 0;
172 }
173 }
174
175 /*
176 * Release mbufs in host table that contain no entries
177 * currently in use. Must be called at splimp.
178 */
hostcompress(unit)179 hostcompress(unit)
180 int unit;
181 {
182 register struct mbuf *m, **mprev;
183 struct imp_softc *sc = &imp_softc[unit];
184
185 mprev = &sc->imp_hosts;
186 sc->imp_hostq = 0;
187 while (m = *mprev) {
188 if (mtod(m, struct hmbuf *)->hm_count == 0)
189 *mprev = m_free(m);
190 else
191 mprev = &m->m_next;
192 }
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 */
hostslowtimo()202 hostslowtimo()
203 {
204 register struct mbuf *m;
205 register struct host *hp, *lp;
206 struct imp_softc *sc;
207 struct hmbuf *hm;
208 int s = splimp(), unit, any;
209
210 for (unit = 0; unit < NIMP; unit++) {
211 any = 0;
212 sc = &imp_softc[unit];
213 for (m = sc->imp_hosts; m; m = m->m_next) {
214 hm = mtod(m, struct hmbuf *);
215 hp = hm->hm_hosts;
216 lp = hp + HPMBUF;
217 for (; hm->hm_count > 0 && hp < lp; hp++) {
218 if (hp->h_timer && --hp->h_timer == 0) {
219 if (hp->h_rfnm) {
220 log(LOG_INFO, /* XXX */
221 "imp%d: host %d/imp %d, lost rfnm\n",
222 unit, hp->h_host, ntohs(hp->h_imp));
223 sc->imp_lostrfnm++;
224 imprestarthost(sc, hp);
225 } else {
226 any = 1;
227 hostrelease(hp);
228 if (sc->imp_hostq == m)
229 sc->imp_hostq = 0;
230 }
231 }
232 }
233 }
234 if (any)
235 hostcompress(unit);
236 }
237 splx(s);
238 }
239 #endif
240