1 /*	if_imphost.c	4.9	82/03/16	*/
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"
14 #include "../net/if_imp.h"
15 #include "../net/if_imphost.h"
16 
17 /*
18  * Head of host table hash chains.
19  */
20 struct mbuf *hosts;
21 
22 /*
23  * Given an internet address
24  * return a host structure (if it exists).
25  */
26 struct host *
27 hostlookup(addr)
28 	struct in_addr addr;
29 {
30 	register struct host *hp;
31 	register struct mbuf *m;
32 	register int hash = HOSTHASH(addr);
33 
34 COUNT(HOSTLOOKUP);
35 	for (m = hosts; m; m = m->m_next) {
36 		hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
37 		if (hp->h_refcnt == 0)
38 			continue;
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 *
51 hostenter(addr)
52 	struct in_addr addr;
53 {
54 	register struct mbuf *m, **mprev;
55 	register struct host *hp, *hp0 = 0;
56 	register int hash = HOSTHASH(addr);
57 
58 COUNT(HOSTENTER);
59 	mprev = &hosts;
60 	while (m = *mprev) {
61 		mprev = &m->m_next;
62 		hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
63 		if (hp->h_refcnt == 0) {
64 			if (hp0 == 0)
65 				hp0 = hp;
66 			continue;
67 		}
68 	        if (hp->h_addr.s_addr == addr.s_addr)
69 			goto foundhost;
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 	 */
77 	if (hp0 == 0) {
78 		m = m_getclr(M_DONTWAIT);
79 		if (m == 0)
80 			return (0);
81 		*mprev = m;
82 		m->m_off = MMINOFF;
83 		hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash];
84 	}
85 	mtod(dtom(hp0), struct hmbuf *)->hm_count++;
86 	hp = hp0;
87 	hp->h_addr = addr;
88 	hp->h_qcnt = 0;
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  */
99 hostfree(hp)
100 	register struct host *hp;
101 {
102 COUNT(HOSTFREE);
103 	if (--hp->h_refcnt)
104 		return;
105 	hostrelease(hp);
106 }
107 
108 /*
109  * Reset a given network's host entries.
110  * This involves clearing all packet queue's
111  * and releasing host structures.
112  */
113 hostreset(net)
114 	int net;
115 {
116 	register struct mbuf *m;
117 	register struct host *hp, *lp;
118 	struct hmbuf *hm;
119 	int x;
120 
121 COUNT(HOSTRESET);
122 	x = splimp();
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_addr.s_net == net) {
129 				hp->h_refcnt = 0;
130 				hostrelease(hp);
131 			}
132 			hp++;
133 		}
134 	}
135 	splx(x);
136 }
137 
138 /*
139  * Remove a host structure and release
140  * any resources it's accumulated.
141  */
142 hostrelease(hp)
143 	register struct host *hp;
144 {
145 	register struct mbuf *m, **mprev, *mh = dtom(hp);
146 
147 COUNT(HOSTRELEASE);
148 	/*
149 	 * Discard any packets left on the waiting q
150 	 */
151 	if (m = hp->h_q) {
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);
159 		hp->h_q = 0;
160 	}
161 	if (--mtod(mh, struct hmbuf *)->hm_count)
162 		return;
163 	mprev = &hosts;
164 	while ((m = *mprev) != mh)
165 		mprev = &m->m_next;
166 	*mprev = mh->m_next;
167 	(void) m_free(mh);
168 }
169 
170 /*
171  * Remove a packet from the holding q.
172  * The RFNM counter is also bumped.
173  */
174 struct mbuf *
175 hostdeque(hp)
176 	register struct host *hp;
177 {
178 	register struct mbuf *m;
179 
180 	hp->h_rfnm--;
181 	HOST_DEQUE(hp, m);
182 	if (m)
183 		return (m);
184 	if (hp->h_rfnm == 0)
185 		hostfree(hp);
186 	return (0);
187 }
188