Commit | Line | Data |
---|---|---|
654fef96 | 1 | /* if_imphost.c 4.4 82/02/16 */ |
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); | |
33 | ||
a2cd4df7 | 34 | COUNT(HOSTLOOKUP); |
41e530c7 | 35 | for (m = hosts; m; m = m->m_next) { |
276c51cf SL |
36 | hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; |
37 | if (hp->h_refcnt == 0) | |
41e530c7 | 38 | continue; |
276c51cf SL |
39 | if (hp->h_addr.s_addr == addr.s_addr) |
40 | return (hp); | |
41 | } | |
42 | return (0); | |
43 | } | |
44 | ||
45 | /* | |
46 | * Enter a reference to this host's internet | |
47 | * address. If no host structure exists, create | |
48 | * one and hook it into the host database. | |
49 | */ | |
50 | struct host * | |
a2cd4df7 | 51 | hostenter(addr) |
276c51cf SL |
52 | struct in_addr addr; |
53 | { | |
41e530c7 BJ |
54 | register struct mbuf *m, **mprev; |
55 | register struct host *hp, *hp0 = 0; | |
276c51cf SL |
56 | register int hash = HOSTHASH(addr); |
57 | ||
a2cd4df7 | 58 | COUNT(HOSTENTER); |
41e530c7 BJ |
59 | mprev = &hosts; |
60 | while (m = *mprev) { | |
276c51cf | 61 | hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; |
41e530c7 BJ |
62 | if (hp->h_refcnt == 0) { |
63 | if (hp0 == 0) | |
64 | hp0 = hp; | |
65 | continue; | |
66 | } | |
276c51cf SL |
67 | if (hp->h_addr.s_addr == addr.s_addr) |
68 | goto foundhost; | |
41e530c7 | 69 | mprev = &m->m_next; |
276c51cf SL |
70 | } |
71 | ||
72 | /* | |
73 | * No current host structure, make one. | |
74 | * If our search ran off the end of the | |
75 | * chain of mbuf's, allocate another. | |
76 | */ | |
41e530c7 | 77 | if (hp0 == 0) { |
276c51cf SL |
78 | m = m_getclr(M_DONTWAIT); |
79 | if (m == 0) | |
80 | return (0); | |
41e530c7 BJ |
81 | *mprev = m; |
82 | m->m_off = MMINOFF; | |
83 | hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; | |
276c51cf | 84 | } |
41e530c7 BJ |
85 | mtod(dtom(hp0), struct hmbuf *)->hm_count++; |
86 | hp = hp0; | |
276c51cf SL |
87 | hp->h_addr = addr; |
88 | hp->h_status = HOSTS_UP; | |
89 | ||
90 | foundhost: | |
91 | hp->h_refcnt++; /* know new structures have 0 val */ | |
92 | return (hp); | |
93 | } | |
94 | ||
95 | /* | |
96 | * Free a reference to a host. If this causes the | |
97 | * host structure to be released do so. | |
98 | */ | |
41e530c7 BJ |
99 | hostfree(hp) |
100 | register struct host *hp; | |
276c51cf SL |
101 | { |
102 | register struct mbuf *m; | |
276c51cf | 103 | |
a2cd4df7 | 104 | COUNT(HOSTFREE); |
41e530c7 BJ |
105 | if (--hp->h_refcnt) |
106 | return; | |
107 | hostrelease(hp); | |
276c51cf SL |
108 | } |
109 | ||
110 | /* | |
111 | * Reset a given network's host entries. | |
112 | * This involves clearing all packet queue's | |
113 | * and releasing host structures. | |
114 | */ | |
a2cd4df7 | 115 | hostreset(net) |
276c51cf SL |
116 | int net; |
117 | { | |
118 | register struct mbuf *m; | |
119 | register struct host *hp, *lp; | |
41e530c7 BJ |
120 | struct hmbuf *hm; |
121 | int x; | |
276c51cf | 122 | |
a2cd4df7 | 123 | COUNT(HOSTRESET); |
41e530c7 BJ |
124 | x = splimp(); |
125 | for (m = hosts; m; m = m->m_next) { | |
126 | hm = mtod(m, struct hmbuf *); | |
127 | hp = hm->hm_hosts; | |
276c51cf | 128 | lp = hp + HPMBUF; |
41e530c7 | 129 | while (hm->hm_count != 0 && hp < lp) { |
276c51cf | 130 | if (hp->h_addr.s_net == net) |
a2cd4df7 | 131 | hostrelease(mtod(m, struct hmbuf *), hp); |
276c51cf SL |
132 | hp++; |
133 | } | |
134 | } | |
41e530c7 | 135 | splx(x); |
276c51cf SL |
136 | } |
137 | ||
138 | /* | |
139 | * Remove a host structure and release | |
140 | * any resources it's accumulated. | |
141 | */ | |
41e530c7 | 142 | hostrelease(hp) |
276c51cf SL |
143 | register struct host *hp; |
144 | { | |
41e530c7 | 145 | register struct mbuf *m, **mprev, *mh = dtom(hp); |
276c51cf | 146 | |
a2cd4df7 | 147 | COUNT(HOSTRELEASE); |
276c51cf SL |
148 | /* |
149 | * Discard any packets left on the waiting q | |
150 | */ | |
a2cd4df7 | 151 | if (m = hp->h_q) { |
654fef96 BJ |
152 | register struct mbuf *n; |
153 | ||
154 | do { | |
155 | n = m->m_act; | |
156 | m_freem(m); | |
157 | m = n; | |
158 | } while (m != hp->h_q); | |
a2cd4df7 | 159 | hp->h_q = 0; |
276c51cf | 160 | } |
41e530c7 | 161 | if (--mtod(mh, struct hmbuf *)->hm_count) |
276c51cf | 162 | return; |
41e530c7 BJ |
163 | mprev = &hosts; |
164 | while ((m = *mprev) != mh) | |
165 | mprev = &m->m_next; | |
166 | *mprev = mh->m_next; | |
167 | (void) m_free(mh); | |
276c51cf | 168 | } |