123168Smckusick /*
233453Skarels  * Copyright (c) 1982,1986,1988 Regents of the University of California.
333453Skarels  * All rights reserved.
423168Smckusick  *
533453Skarels  * Redistribution and use in source and binary forms are permitted
633453Skarels  * provided that this notice is preserved and that due credit is given
733453Skarels  * to the University of California at Berkeley. The name of the University
833453Skarels  * may not be used to endorse or promote products derived from this
933453Skarels  * software without specific prior written permission. This software
1033453Skarels  * is provided ``as is'' without express or implied warranty.
1133453Skarels  *
12*34459Skarels  *	@(#)if_imphost.c	7.7 (Berkeley) 05/24/88
1323168Smckusick  */
145712Ssam 
155712Ssam #include "imp.h"
165712Ssam #if NIMP > 0
175712Ssam /*
185712Ssam  * Host table manipulation routines.
195712Ssam  * Only needed when shipping stuff through an IMP.
2011231Ssam  *
2111231Ssam  * Everything in here is called at splimp from
2211231Ssam  * from the IMP protocol code (if_imp.c), or
2311231Ssam  * interlocks with the code at splimp.
245712Ssam  */
2517069Sbloom #include "param.h"
2617069Sbloom #include "mbuf.h"
2733427Skarels #include "socket.h"
2824778Skarels #include "syslog.h"
2911231Ssam 
3033427Skarels #include "../net/if.h"
3133427Skarels 
328412Swnj #include "../netinet/in.h"
338412Swnj #include "../netinet/in_systm.h"
3411231Ssam 
3517069Sbloom #include "if_imp.h"
3617069Sbloom #include "if_imphost.h"
375712Ssam 
3833427Skarels extern struct imp_softc imp_softc[];
395712Ssam 
405712Ssam /*
415712Ssam  * Given an internet address
425712Ssam  * return a host structure (if it exists).
435712Ssam  */
445712Ssam struct host *
4533427Skarels hostlookup(imp, host, unit)
4633427Skarels 	int imp, host, unit;
475712Ssam {
485712Ssam 	register struct host *hp;
495712Ssam 	register struct mbuf *m;
5033427Skarels 	register int hash = HOSTHASH(imp, host);
515712Ssam 
5233453Skarels 	for (m = imp_softc[unit].imp_hosts; m; m = m->m_next) {
535712Ssam 		hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
5433453Skarels 	        if (hp->h_imp == imp && hp->h_host == host) {
5534209Skarels 			if ((hp->h_flags & HF_INUSE) == 0)
5633453Skarels 				mtod(dtom(hp), struct hmbuf *)->hm_count++;
576589Ssam 			hp->h_flags |= HF_INUSE;
5811231Ssam 			return (hp);
596589Ssam 		}
605712Ssam 	}
6111231Ssam 	return ((struct host *)0);
625712Ssam }
635712Ssam 
645712Ssam /*
655712Ssam  * Enter a reference to this host's internet
665712Ssam  * address.  If no host structure exists, create
675712Ssam  * one and hook it into the host database.
685712Ssam  */
695712Ssam struct host *
7033427Skarels hostenter(imp, host, unit)
7133427Skarels 	int imp, host, unit;
725712Ssam {
735860Sroot 	register struct mbuf *m, **mprev;
745860Sroot 	register struct host *hp, *hp0 = 0;
7533427Skarels 	register int hash = HOSTHASH(imp, host);
765712Ssam 
7733453Skarels 	mprev = &imp_softc[unit].imp_hosts;
785860Sroot 	while (m = *mprev) {
796209Swnj 		mprev = &m->m_next;
805712Ssam 		hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
8133453Skarels 	        if (hp->h_imp == imp && hp->h_host == host) {
8234209Skarels 			if ((hp->h_flags & HF_INUSE) == 0)
8333453Skarels 				mtod(dtom(hp), struct hmbuf *)->hm_count++;
8433427Skarels 			goto foundhost;
8533453Skarels 		}
866589Ssam 		if ((hp->h_flags & HF_INUSE) == 0) {
875860Sroot 			if (hp0 == 0)
885860Sroot 				hp0 = hp;
895860Sroot 			continue;
905860Sroot 		}
915712Ssam 	}
925712Ssam 
935712Ssam 	/*
945712Ssam 	 * No current host structure, make one.
955712Ssam 	 * If our search ran off the end of the
965712Ssam 	 * chain of mbuf's, allocate another.
975712Ssam 	 */
985860Sroot 	if (hp0 == 0) {
999646Ssam 		m = m_getclr(M_DONTWAIT, MT_HTABLE);
10011231Ssam 		if (m == NULL)
10111231Ssam 			return ((struct host *)0);
1025860Sroot 		*mprev = m;
1035860Sroot 		hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash];
1045712Ssam 	}
1055860Sroot 	hp = hp0;
10634209Skarels 	mtod(dtom(hp), struct hmbuf *)->hm_count++;
10733427Skarels 	hp->h_imp = imp;
10833427Skarels 	hp->h_host = host;
1096589Ssam 	hp->h_timer = 0;
1106725Ssam 	hp->h_flags = 0;
1115712Ssam 
1125712Ssam foundhost:
1136589Ssam 	hp->h_flags |= HF_INUSE;
1145712Ssam 	return (hp);
1155712Ssam }
1165712Ssam 
1175712Ssam /*
11833427Skarels  * Reset a given imp unit's host entries.
1195712Ssam  */
12033427Skarels hostreset(unit)
12133427Skarels 	int unit;
1225712Ssam {
1235712Ssam 	register struct mbuf *m;
1245712Ssam 	register struct host *hp, *lp;
1255860Sroot 	struct hmbuf *hm;
1265712Ssam 
12733453Skarels 	for (m = imp_softc[unit].imp_hosts; m; m = m->m_next) {
1285860Sroot 		hm = mtod(m, struct hmbuf *);
1295860Sroot 		hp = hm->hm_hosts;
1305712Ssam 		lp = hp + HPMBUF;
1316589Ssam 		while (hm->hm_count > 0 && hp < lp) {
13233453Skarels 			hostrelease(hp);
1335712Ssam 			hp++;
1345712Ssam 		}
1355712Ssam 	}
13633453Skarels 	hostcompress(unit);
1375712Ssam }
1385712Ssam 
1395712Ssam /*
1405712Ssam  * Remove a host structure and release
1415712Ssam  * any resources it's accumulated.
1425712Ssam  */
1435860Sroot hostrelease(hp)
1445712Ssam 	register struct host *hp;
1455712Ssam {
1465712Ssam 
14734209Skarels 	if (hp->h_q)
14834209Skarels 		hostflush(hp);
14934209Skarels 	hp->h_rfnm = 0;
15034209Skarels 	if (hp->h_flags & HF_INUSE)
15134209Skarels 		--mtod(dtom(hp), struct hmbuf *)->hm_count;
15233453Skarels 	hp->h_flags = 0;
15333453Skarels }
15433453Skarels 
15533453Skarels /*
15633453Skarels  * Flush the message queue for a host.
15733453Skarels  */
15833453Skarels hostflush(hp)
15933453Skarels 	register struct host *hp;
16033453Skarels {
161*34459Skarels 	register struct mbuf *m;
16233453Skarels 
1635712Ssam 	/*
1645712Ssam 	 * Discard any packets left on the waiting q
1655712Ssam 	 */
1665771Swnj 	if (m = hp->h_q) {
1675868Sroot 		register struct mbuf *n;
1685868Sroot 
1695868Sroot 		do {
1705868Sroot 			n = m->m_act;
1715868Sroot 			m_freem(m);
1725868Sroot 			m = n;
1735868Sroot 		} while (m != hp->h_q);
1745771Swnj 		hp->h_q = 0;
17533453Skarels 		hp->h_qcnt = 0;
1765712Ssam 	}
1775712Ssam }
1785924Sroot 
17933453Skarels hostcompress(unit)
18033453Skarels 	int unit;
1815924Sroot {
18233427Skarels 	register struct mbuf *m, **mprev;
1835924Sroot 
18433453Skarels 	mprev = &imp_softc[unit].imp_hosts;
18533427Skarels 	while (m = *mprev) {
18633427Skarels 		if (mtod(m, struct hmbuf *)->hm_count == 0)
18733427Skarels 			*mprev = m_free(m);
18833427Skarels 		else
18933427Skarels 			mprev = &m->m_next;
19033427Skarels 	}
1915924Sroot }
1926589Ssam 
1936589Ssam /*
1946589Ssam  * Host data base timer routine.
1956589Ssam  * Decrement timers on structures which are
1966589Ssam  * waiting to be deallocated.  On expiration
1976589Ssam  * release resources, possibly deallocating
1986589Ssam  * mbuf associated with structure.
1996589Ssam  */
2006589Ssam hostslowtimo()
2016589Ssam {
2026589Ssam 	register struct mbuf *m;
2036589Ssam 	register struct host *hp, *lp;
20433454Skarels 	struct imp_softc *sc;
2056589Ssam 	struct hmbuf *hm;
20633453Skarels 	int s = splimp(), unit, any;
2076589Ssam 
20833453Skarels 	for (unit = 0; unit < NIMP; unit++) {
20933453Skarels 	    any = 0;
21033454Skarels 	    sc = &imp_softc[unit];
21133454Skarels 	    for (m = sc->imp_hosts; m; m = m->m_next) {
2126589Ssam 		hm = mtod(m, struct hmbuf *);
2136589Ssam 		hp = hm->hm_hosts;
2146589Ssam 		lp = hp + HPMBUF;
2156779Ssam 		for (; hm->hm_count > 0 && hp < lp; hp++) {
21633427Skarels 		    if (hp->h_timer && --hp->h_timer == 0) {
21733427Skarels 			if (hp->h_rfnm) {
21834260Skarels 				log(LOG_INFO,			/* XXX */
21933453Skarels 				    "imp%d: host %d/imp %d, lost rfnm\n",
22033453Skarels 				    unit, hp->h_host, ntohs(hp->h_imp));
22134209Skarels 				sc->imp_lostrfnm++;
22234209Skarels 				imprestarthost(sc, hp);
22334209Skarels 			} else {
22433453Skarels 				any = 1;
22533453Skarels 				hostrelease(hp);
22633454Skarels 				if (sc->imp_hostq == m)
22733454Skarels 					sc->imp_hostq = 0;
22833453Skarels 			}
22933427Skarels 		    }
2306589Ssam 		}
23133453Skarels 	    }
23234209Skarels 	    if (any)
23333453Skarels 		hostcompress(unit);
2346589Ssam 	}
23511241Ssam 	splx(s);
2366589Ssam }
23713081Ssam #endif
238