123168Smckusick /*
229081Smckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
323168Smckusick  * All rights reserved.  The Berkeley software License Agreement
423168Smckusick  * specifies the terms and conditions for redistribution.
523168Smckusick  *
6*33427Skarels  *	@(#)if_imphost.c	7.2 (Berkeley) 02/03/88
723168Smckusick  */
85712Ssam 
95712Ssam #include "imp.h"
105712Ssam #if NIMP > 0
115712Ssam /*
125712Ssam  * Host table manipulation routines.
135712Ssam  * Only needed when shipping stuff through an IMP.
1411231Ssam  *
1511231Ssam  * Everything in here is called at splimp from
1611231Ssam  * from the IMP protocol code (if_imp.c), or
1711231Ssam  * interlocks with the code at splimp.
185712Ssam  */
1917069Sbloom #include "param.h"
2017069Sbloom #include "mbuf.h"
21*33427Skarels #include "socket.h"
2224778Skarels #include "syslog.h"
2311231Ssam 
24*33427Skarels #include "../net/if.h"
25*33427Skarels 
268412Swnj #include "../netinet/in.h"
278412Swnj #include "../netinet/in_systm.h"
2811231Ssam 
2917069Sbloom #include "if_imp.h"
3017069Sbloom #include "if_imphost.h"
315712Ssam 
325712Ssam /*
335712Ssam  * Head of host table hash chains.
345712Ssam  */
355860Sroot struct mbuf *hosts;
36*33427Skarels extern struct imp_softc imp_softc[];
375712Ssam 
385712Ssam /*
395712Ssam  * Given an internet address
405712Ssam  * return a host structure (if it exists).
415712Ssam  */
425712Ssam struct host *
43*33427Skarels hostlookup(imp, host, unit)
44*33427Skarels 	int imp, host, unit;
455712Ssam {
465712Ssam 	register struct host *hp;
475712Ssam 	register struct mbuf *m;
48*33427Skarels 	register int hash = HOSTHASH(imp, host);
495712Ssam 
505860Sroot 	for (m = hosts; m; m = m->m_next) {
515712Ssam 		hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
52*33427Skarels 	        if (hp->h_imp == imp && hp->h_host == host &&
53*33427Skarels 		    hp->h_unit == unit) {
546589Ssam 			hp->h_flags |= HF_INUSE;
5511231Ssam 			return (hp);
566589Ssam 		}
575712Ssam 	}
5811231Ssam 	return ((struct host *)0);
595712Ssam }
605712Ssam 
615712Ssam /*
625712Ssam  * Enter a reference to this host's internet
635712Ssam  * address.  If no host structure exists, create
645712Ssam  * one and hook it into the host database.
655712Ssam  */
665712Ssam struct host *
67*33427Skarels hostenter(imp, host, unit)
68*33427Skarels 	int imp, host, unit;
695712Ssam {
705860Sroot 	register struct mbuf *m, **mprev;
715860Sroot 	register struct host *hp, *hp0 = 0;
72*33427Skarels 	register int hash = HOSTHASH(imp, host);
735712Ssam 
745860Sroot 	mprev = &hosts;
755860Sroot 	while (m = *mprev) {
766209Swnj 		mprev = &m->m_next;
775712Ssam 		hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
78*33427Skarels 	        if (hp->h_imp == imp && hp->h_host == host &&
79*33427Skarels 		    hp->h_unit == unit)
80*33427Skarels 			goto foundhost;
816589Ssam 		if ((hp->h_flags & HF_INUSE) == 0) {
825860Sroot 			if (hp0 == 0)
835860Sroot 				hp0 = hp;
845860Sroot 			continue;
855860Sroot 		}
865712Ssam 	}
875712Ssam 
885712Ssam 	/*
895712Ssam 	 * No current host structure, make one.
905712Ssam 	 * If our search ran off the end of the
915712Ssam 	 * chain of mbuf's, allocate another.
925712Ssam 	 */
935860Sroot 	if (hp0 == 0) {
949646Ssam 		m = m_getclr(M_DONTWAIT, MT_HTABLE);
9511231Ssam 		if (m == NULL)
9611231Ssam 			return ((struct host *)0);
975860Sroot 		*mprev = m;
985860Sroot 		hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash];
995712Ssam 	}
1005860Sroot 	mtod(dtom(hp0), struct hmbuf *)->hm_count++;
1015860Sroot 	hp = hp0;
102*33427Skarels 	hp->h_imp = imp;
103*33427Skarels 	hp->h_host = host;
104*33427Skarels 	hp->h_unit = unit;
1056589Ssam 	hp->h_timer = 0;
1066725Ssam 	hp->h_flags = 0;
1075712Ssam 
1085712Ssam foundhost:
1096589Ssam 	hp->h_flags |= HF_INUSE;
1105712Ssam 	return (hp);
1115712Ssam }
1125712Ssam 
1135712Ssam /*
114*33427Skarels  * Reset a given imp unit's host entries.
1155712Ssam  */
116*33427Skarels hostreset(unit)
117*33427Skarels 	int unit;
1185712Ssam {
1195712Ssam 	register struct mbuf *m;
1205712Ssam 	register struct host *hp, *lp;
1215860Sroot 	struct hmbuf *hm;
1225712Ssam 
123*33427Skarels 	for (m = hosts; m; m = m->m_next) {
1245860Sroot 		hm = mtod(m, struct hmbuf *);
1255860Sroot 		hp = hm->hm_hosts;
1265712Ssam 		lp = hp + HPMBUF;
1276589Ssam 		while (hm->hm_count > 0 && hp < lp) {
128*33427Skarels 			if (hp->h_unit == unit)
1296145Ssam 				hostrelease(hp);
1305712Ssam 			hp++;
1315712Ssam 		}
1325712Ssam 	}
133*33427Skarels 	hostcompress();
1345712Ssam }
1355712Ssam 
1365712Ssam /*
1375712Ssam  * Remove a host structure and release
1385712Ssam  * any resources it's accumulated.
1395712Ssam  */
1405860Sroot hostrelease(hp)
1415712Ssam 	register struct host *hp;
1425712Ssam {
1435860Sroot 	register struct mbuf *m, **mprev, *mh = dtom(hp);
1445712Ssam 
1455712Ssam 	/*
1465712Ssam 	 * Discard any packets left on the waiting q
1475712Ssam 	 */
1485771Swnj 	if (m = hp->h_q) {
1495868Sroot 		register struct mbuf *n;
1505868Sroot 
1515868Sroot 		do {
1525868Sroot 			n = m->m_act;
1535868Sroot 			m_freem(m);
1545868Sroot 			m = n;
1555868Sroot 		} while (m != hp->h_q);
1565771Swnj 		hp->h_q = 0;
1575712Ssam 	}
1586725Ssam 	hp->h_flags = 0;
15918133Skarels 	hp->h_rfnm = 0;
160*33427Skarels 	--mtod(mh, struct hmbuf *)->hm_count;
1615712Ssam }
1625924Sroot 
163*33427Skarels hostcompress()
1645924Sroot {
165*33427Skarels 	register struct mbuf *m, **mprev;
1665924Sroot 
167*33427Skarels 	mprev = &hosts;
168*33427Skarels 	while (m = *mprev) {
169*33427Skarels 		if (mtod(m, struct hmbuf *)->hm_count == 0)
170*33427Skarels 			*mprev = m_free(m);
171*33427Skarels 		else
172*33427Skarels 			mprev = &m->m_next;
173*33427Skarels 	}
1745924Sroot }
1756589Ssam 
1766589Ssam /*
1776589Ssam  * Host data base timer routine.
1786589Ssam  * Decrement timers on structures which are
1796589Ssam  * waiting to be deallocated.  On expiration
1806589Ssam  * release resources, possibly deallocating
1816589Ssam  * mbuf associated with structure.
1826589Ssam  */
1836589Ssam hostslowtimo()
1846589Ssam {
1856589Ssam 	register struct mbuf *m;
1866589Ssam 	register struct host *hp, *lp;
1876589Ssam 	struct hmbuf *hm;
188*33427Skarels 	int s = splimp(), any = 0;
1896589Ssam 
190*33427Skarels 	for (m = hosts; m; m = m->m_next) {
1916589Ssam 		hm = mtod(m, struct hmbuf *);
1926589Ssam 		hp = hm->hm_hosts;
1936589Ssam 		lp = hp + HPMBUF;
1946779Ssam 		for (; hm->hm_count > 0 && hp < lp; hp++) {
195*33427Skarels 		    if (hp->h_timer && --hp->h_timer == 0) {
196*33427Skarels 			if (hp->h_rfnm) {
197*33427Skarels 			    log(LOG_WARNING,
198*33427Skarels 			        "imp%d: host %d/imp %d, lost %d rfnms\n",
199*33427Skarels 			        hp->h_unit, hp->h_host, ntohs(hp->h_imp),
200*33427Skarels 			        hp->h_rfnm);
201*33427Skarels 			    imp_softc[hp->h_unit].imp_lostrfnm += hp->h_rfnm;
202*33427Skarels 			    hp->h_rfnm = 0;
203*33427Skarels 			    if (hp->h_q) {
204*33427Skarels 				imprestarthost(hp);
205*33427Skarels 				continue;
206*33427Skarels 			    }
20724778Skarels 			}
208*33427Skarels 			any = 1;
209*33427Skarels 			hostrelease(hp);
210*33427Skarels 		    }
2116589Ssam 		}
2126589Ssam 	}
213*33427Skarels 	if (any)
214*33427Skarels 		hostcompress();
21511241Ssam 	splx(s);
2166589Ssam }
21713081Ssam #endif
218