Commit | Line | Data |
---|---|---|
83969adf | 1 | /* if_imphost.c 4.11 82/05/10 */ |
276c51cf SL |
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 "../net/in.h" | |
13 | #include "../net/in_systm.h" | |
276c51cf | 14 | #include "../net/if_imp.h" |
41e530c7 | 15 | #include "../net/if_imphost.h" |
276c51cf SL |
16 | |
17 | /* | |
18 | * Head of host table hash chains. | |
19 | */ | |
41e530c7 | 20 | struct mbuf *hosts; |
276c51cf SL |
21 | |
22 | /* | |
23 | * Given an internet address | |
24 | * return a host structure (if it exists). | |
25 | */ | |
26 | struct host * | |
a2cd4df7 | 27 | hostlookup(addr) |
276c51cf SL |
28 | struct in_addr addr; |
29 | { | |
30 | register struct host *hp; | |
31 | register struct mbuf *m; | |
32 | register int hash = HOSTHASH(addr); | |
ba45553a | 33 | int s = splnet(); |
276c51cf | 34 | |
a2cd4df7 | 35 | COUNT(HOSTLOOKUP); |
41e530c7 | 36 | for (m = hosts; m; m = m->m_next) { |
276c51cf | 37 | hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; |
ba45553a SL |
38 | if (hp->h_addr.s_addr == addr.s_addr) { |
39 | hp->h_flags |= HF_INUSE; | |
40 | goto found; | |
41 | } | |
276c51cf | 42 | } |
ba45553a SL |
43 | hp = 0; |
44 | found: | |
45 | splx(s); | |
46 | return (hp); | |
276c51cf SL |
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 * | |
a2cd4df7 | 55 | hostenter(addr) |
276c51cf SL |
56 | struct in_addr addr; |
57 | { | |
41e530c7 BJ |
58 | register struct mbuf *m, **mprev; |
59 | register struct host *hp, *hp0 = 0; | |
276c51cf | 60 | register int hash = HOSTHASH(addr); |
ba45553a | 61 | int s = splnet(); |
276c51cf | 62 | |
a2cd4df7 | 63 | COUNT(HOSTENTER); |
41e530c7 BJ |
64 | mprev = &hosts; |
65 | while (m = *mprev) { | |
1e977657 | 66 | mprev = &m->m_next; |
276c51cf | 67 | hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; |
ba45553a SL |
68 | if ((hp->h_flags & HF_INUSE) == 0) { |
69 | if (hp->h_addr.s_addr == addr.s_addr) | |
70 | goto foundhost; | |
41e530c7 BJ |
71 | if (hp0 == 0) |
72 | hp0 = hp; | |
73 | continue; | |
74 | } | |
276c51cf SL |
75 | if (hp->h_addr.s_addr == addr.s_addr) |
76 | goto foundhost; | |
77 | } | |
78 | ||
79 | /* | |
80 | * No current host structure, make one. | |
81 | * If our search ran off the end of the | |
82 | * chain of mbuf's, allocate another. | |
83 | */ | |
41e530c7 | 84 | if (hp0 == 0) { |
276c51cf | 85 | m = m_getclr(M_DONTWAIT); |
ba45553a SL |
86 | if (m == 0) { |
87 | splx(s); | |
276c51cf | 88 | return (0); |
ba45553a | 89 | } |
41e530c7 BJ |
90 | *mprev = m; |
91 | m->m_off = MMINOFF; | |
92 | hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; | |
276c51cf | 93 | } |
41e530c7 BJ |
94 | mtod(dtom(hp0), struct hmbuf *)->hm_count++; |
95 | hp = hp0; | |
276c51cf | 96 | hp->h_addr = addr; |
ba45553a | 97 | hp->h_timer = 0; |
83969adf | 98 | hp->h_flags = 0; |
276c51cf SL |
99 | |
100 | foundhost: | |
ba45553a SL |
101 | hp->h_flags |= HF_INUSE; |
102 | splx(s); | |
276c51cf SL |
103 | return (hp); |
104 | } | |
105 | ||
106 | /* | |
ba45553a SL |
107 | * Mark a host structure free and set it's |
108 | * timer going. | |
276c51cf | 109 | */ |
41e530c7 BJ |
110 | hostfree(hp) |
111 | register struct host *hp; | |
276c51cf | 112 | { |
ba45553a SL |
113 | int s = splnet(); |
114 | ||
a2cd4df7 | 115 | COUNT(HOSTFREE); |
ba45553a SL |
116 | hp->h_flags &= ~HF_INUSE; |
117 | hp->h_timer = HOSTTIMER; | |
118 | hp->h_rfnm = 0; | |
119 | splx(s); | |
276c51cf SL |
120 | } |
121 | ||
122 | /* | |
123 | * Reset a given network's host entries. | |
276c51cf | 124 | */ |
a2cd4df7 | 125 | hostreset(net) |
276c51cf SL |
126 | int net; |
127 | { | |
128 | register struct mbuf *m; | |
129 | register struct host *hp, *lp; | |
41e530c7 | 130 | struct hmbuf *hm; |
ba45553a | 131 | int s = splnet(); |
276c51cf | 132 | |
a2cd4df7 | 133 | COUNT(HOSTRESET); |
41e530c7 BJ |
134 | for (m = hosts; m; m = m->m_next) { |
135 | hm = mtod(m, struct hmbuf *); | |
136 | hp = hm->hm_hosts; | |
276c51cf | 137 | lp = hp + HPMBUF; |
ba45553a | 138 | while (hm->hm_count > 0 && hp < lp) { |
c19356d7 | 139 | if (hp->h_addr.s_net == net) { |
ba45553a | 140 | hp->h_flags &= ~HF_INUSE; |
8239b605 | 141 | hostrelease(hp); |
c19356d7 | 142 | } |
276c51cf SL |
143 | hp++; |
144 | } | |
145 | } | |
ba45553a | 146 | splx(s); |
276c51cf SL |
147 | } |
148 | ||
149 | /* | |
150 | * Remove a host structure and release | |
151 | * any resources it's accumulated. | |
ba45553a | 152 | * This routine is always called at splnet. |
276c51cf | 153 | */ |
41e530c7 | 154 | hostrelease(hp) |
276c51cf SL |
155 | register struct host *hp; |
156 | { | |
41e530c7 | 157 | register struct mbuf *m, **mprev, *mh = dtom(hp); |
276c51cf | 158 | |
a2cd4df7 | 159 | COUNT(HOSTRELEASE); |
276c51cf SL |
160 | /* |
161 | * Discard any packets left on the waiting q | |
162 | */ | |
a2cd4df7 | 163 | if (m = hp->h_q) { |
654fef96 BJ |
164 | register struct mbuf *n; |
165 | ||
166 | do { | |
167 | n = m->m_act; | |
168 | m_freem(m); | |
169 | m = n; | |
170 | } while (m != hp->h_q); | |
a2cd4df7 | 171 | hp->h_q = 0; |
276c51cf | 172 | } |
83969adf | 173 | hp->h_flags = 0; |
41e530c7 | 174 | if (--mtod(mh, struct hmbuf *)->hm_count) |
276c51cf | 175 | return; |
41e530c7 BJ |
176 | mprev = &hosts; |
177 | while ((m = *mprev) != mh) | |
178 | mprev = &m->m_next; | |
ba45553a | 179 | *mprev = m_free(mh); |
276c51cf | 180 | } |
e33b5b1a BJ |
181 | |
182 | /* | |
183 | * Remove a packet from the holding q. | |
184 | * The RFNM counter is also bumped. | |
185 | */ | |
186 | struct mbuf * | |
187 | hostdeque(hp) | |
188 | register struct host *hp; | |
189 | { | |
190 | register struct mbuf *m; | |
191 | ||
192 | hp->h_rfnm--; | |
193 | HOST_DEQUE(hp, m); | |
194 | if (m) | |
195 | return (m); | |
196 | if (hp->h_rfnm == 0) | |
197 | hostfree(hp); | |
198 | return (0); | |
199 | } | |
ba45553a SL |
200 | |
201 | /* | |
202 | * Host data base timer routine. | |
203 | * Decrement timers on structures which are | |
204 | * waiting to be deallocated. On expiration | |
205 | * release resources, possibly deallocating | |
206 | * mbuf associated with structure. | |
207 | */ | |
208 | hostslowtimo() | |
209 | { | |
210 | register struct mbuf *m; | |
211 | register struct host *hp, *lp; | |
212 | struct hmbuf *hm; | |
213 | int s = splnet(); | |
214 | ||
215 | COUNT(HOSTSLOWTIMO); | |
216 | for (m = hosts; m; m = m->m_next) { | |
217 | hm = mtod(m, struct hmbuf *); | |
218 | hp = hm->hm_hosts; | |
219 | lp = hp + HPMBUF; | |
220 | while (hm->hm_count > 0 && hp < lp) { | |
221 | if (hp->h_flags & HF_INUSE) | |
222 | continue; | |
223 | if (hp->h_timer && --hp->h_timer == 0) | |
224 | hostrelease(hp); | |
225 | hp++; | |
226 | } | |
227 | } | |
228 | splx(s); | |
229 | } |