1*23168Smckusick /*
2*23168Smckusick  * Copyright (c) 1982 Regents of the University of California.
3*23168Smckusick  * All rights reserved.  The Berkeley software License Agreement
4*23168Smckusick  * specifies the terms and conditions for redistribution.
5*23168Smckusick  *
6*23168Smckusick  *	@(#)if_imphost.c	6.4 (Berkeley) 06/08/85
7*23168Smckusick  */
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"
2111231Ssam 
228412Swnj #include "../netinet/in.h"
238412Swnj #include "../netinet/in_systm.h"
2411231Ssam 
2517069Sbloom #include "if_imp.h"
2617069Sbloom #include "if_imphost.h"
275712Ssam 
285712Ssam /*
295712Ssam  * Head of host table hash chains.
305712Ssam  */
315860Sroot struct mbuf *hosts;
325712Ssam 
335712Ssam /*
345712Ssam  * Given an internet address
355712Ssam  * return a host structure (if it exists).
365712Ssam  */
375712Ssam struct host *
385771Swnj hostlookup(addr)
395712Ssam 	struct in_addr addr;
405712Ssam {
415712Ssam 	register struct host *hp;
425712Ssam 	register struct mbuf *m;
435712Ssam 	register int hash = HOSTHASH(addr);
445712Ssam 
455860Sroot 	for (m = hosts; m; m = m->m_next) {
465712Ssam 		hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
476589Ssam 	        if (hp->h_addr.s_addr == addr.s_addr) {
486589Ssam 			hp->h_flags |= HF_INUSE;
4911231Ssam 			return (hp);
506589Ssam 		}
515712Ssam 	}
5211231Ssam 	return ((struct host *)0);
535712Ssam }
545712Ssam 
555712Ssam /*
565712Ssam  * Enter a reference to this host's internet
575712Ssam  * address.  If no host structure exists, create
585712Ssam  * one and hook it into the host database.
595712Ssam  */
605712Ssam struct host *
615771Swnj hostenter(addr)
625712Ssam 	struct in_addr addr;
635712Ssam {
645860Sroot 	register struct mbuf *m, **mprev;
655860Sroot 	register struct host *hp, *hp0 = 0;
665712Ssam 	register int hash = HOSTHASH(addr);
675712Ssam 
685860Sroot 	mprev = &hosts;
695860Sroot 	while (m = *mprev) {
706209Swnj 		mprev = &m->m_next;
715712Ssam 		hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
726589Ssam 		if ((hp->h_flags & HF_INUSE) == 0) {
736589Ssam 			if (hp->h_addr.s_addr == addr.s_addr)
746589Ssam 				goto foundhost;
755860Sroot 			if (hp0 == 0)
765860Sroot 				hp0 = hp;
775860Sroot 			continue;
785860Sroot 		}
795712Ssam 	        if (hp->h_addr.s_addr == addr.s_addr)
805712Ssam 			goto foundhost;
815712Ssam 	}
825712Ssam 
835712Ssam 	/*
845712Ssam 	 * No current host structure, make one.
855712Ssam 	 * If our search ran off the end of the
865712Ssam 	 * chain of mbuf's, allocate another.
875712Ssam 	 */
885860Sroot 	if (hp0 == 0) {
899646Ssam 		m = m_getclr(M_DONTWAIT, MT_HTABLE);
9011231Ssam 		if (m == NULL)
9111231Ssam 			return ((struct host *)0);
925860Sroot 		*mprev = m;
935860Sroot 		hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash];
945712Ssam 	}
955860Sroot 	mtod(dtom(hp0), struct hmbuf *)->hm_count++;
965860Sroot 	hp = hp0;
975712Ssam 	hp->h_addr = addr;
986589Ssam 	hp->h_timer = 0;
996725Ssam 	hp->h_flags = 0;
1005712Ssam 
1015712Ssam foundhost:
1026589Ssam 	hp->h_flags |= HF_INUSE;
1035712Ssam 	return (hp);
1045712Ssam }
1055712Ssam 
1065712Ssam /*
1076589Ssam  * Mark a host structure free and set it's
1086589Ssam  * timer going.
1095712Ssam  */
1105860Sroot hostfree(hp)
1115860Sroot 	register struct host *hp;
1125712Ssam {
1136589Ssam 
1146589Ssam 	hp->h_flags &= ~HF_INUSE;
1156589Ssam 	hp->h_timer = HOSTTIMER;
1166589Ssam 	hp->h_rfnm = 0;
1175712Ssam }
1185712Ssam 
1195712Ssam /*
1205712Ssam  * Reset a given network's host entries.
1215712Ssam  */
1225771Swnj hostreset(net)
12318133Skarels 	long net;
1245712Ssam {
1255712Ssam 	register struct mbuf *m;
1265712Ssam 	register struct host *hp, *lp;
1275860Sroot 	struct hmbuf *hm;
1285712Ssam 
1295860Sroot 	for (m = hosts; m; m = m->m_next) {
1305860Sroot 		hm = mtod(m, struct hmbuf *);
1315860Sroot 		hp = hm->hm_hosts;
1325712Ssam 		lp = hp + HPMBUF;
1336589Ssam 		while (hm->hm_count > 0 && hp < lp) {
13418133Skarels 			if (in_netof(hp->h_addr) == net) {
1356589Ssam 				hp->h_flags &= ~HF_INUSE;
1366145Ssam 				hostrelease(hp);
1376089Sroot 			}
1385712Ssam 			hp++;
1395712Ssam 		}
1405712Ssam 	}
1415712Ssam }
1425712Ssam 
1435712Ssam /*
1445712Ssam  * Remove a host structure and release
1455712Ssam  * any resources it's accumulated.
1465712Ssam  */
1475860Sroot hostrelease(hp)
1485712Ssam 	register struct host *hp;
1495712Ssam {
1505860Sroot 	register struct mbuf *m, **mprev, *mh = dtom(hp);
1515712Ssam 
1525712Ssam 	/*
1535712Ssam 	 * Discard any packets left on the waiting q
1545712Ssam 	 */
1555771Swnj 	if (m = hp->h_q) {
1565868Sroot 		register struct mbuf *n;
1575868Sroot 
1585868Sroot 		do {
1595868Sroot 			n = m->m_act;
1605868Sroot 			m_freem(m);
1615868Sroot 			m = n;
1625868Sroot 		} while (m != hp->h_q);
1635771Swnj 		hp->h_q = 0;
1645712Ssam 	}
1656725Ssam 	hp->h_flags = 0;
16618133Skarels 	hp->h_rfnm = 0;
1675860Sroot 	if (--mtod(mh, struct hmbuf *)->hm_count)
1685712Ssam 		return;
1695860Sroot 	mprev = &hosts;
1705860Sroot 	while ((m = *mprev) != mh)
1715860Sroot 		mprev = &m->m_next;
1726589Ssam 	*mprev = m_free(mh);
1735712Ssam }
1745924Sroot 
1755924Sroot /*
1765924Sroot  * Remove a packet from the holding q.
1775924Sroot  * The RFNM counter is also bumped.
1785924Sroot  */
1795924Sroot struct mbuf *
1805924Sroot hostdeque(hp)
1815924Sroot 	register struct host *hp;
1825924Sroot {
1835924Sroot 	register struct mbuf *m;
1845924Sroot 
1855924Sroot 	hp->h_rfnm--;
1865924Sroot 	HOST_DEQUE(hp, m);
1875924Sroot 	if (m)
1885924Sroot 		return (m);
1895924Sroot 	if (hp->h_rfnm == 0)
1905924Sroot 		hostfree(hp);
1915924Sroot 	return (0);
1925924Sroot }
1936589Ssam 
1946589Ssam /*
1956589Ssam  * Host data base timer routine.
1966589Ssam  * Decrement timers on structures which are
1976589Ssam  * waiting to be deallocated.  On expiration
1986589Ssam  * release resources, possibly deallocating
1996589Ssam  * mbuf associated with structure.
2006589Ssam  */
2016589Ssam hostslowtimo()
2026589Ssam {
2036589Ssam 	register struct mbuf *m;
2046589Ssam 	register struct host *hp, *lp;
2056589Ssam 	struct hmbuf *hm;
20611231Ssam 	int s = splimp();
2076589Ssam 
2086589Ssam 	for (m = hosts; m; m = m->m_next) {
2096589Ssam 		hm = mtod(m, struct hmbuf *);
2106589Ssam 		hp = hm->hm_hosts;
2116589Ssam 		lp = hp + HPMBUF;
2126779Ssam 		for (; hm->hm_count > 0 && hp < lp; hp++) {
2136589Ssam 			if (hp->h_flags & HF_INUSE)
2146589Ssam 				continue;
2156589Ssam 			if (hp->h_timer && --hp->h_timer == 0)
2166589Ssam 				hostrelease(hp);
2176589Ssam 		}
2186589Ssam 	}
21911241Ssam 	splx(s);
2206589Ssam }
22113081Ssam #endif
222