1*6089Sroot /* if_imphost.c 4.6 82/03/09 */ 25712Ssam 35712Ssam #include "imp.h" 45712Ssam #if NIMP > 0 55712Ssam /* 65712Ssam * Host table manipulation routines. 75712Ssam * Only needed when shipping stuff through an IMP. 85712Ssam */ 95712Ssam 105712Ssam #include "../h/param.h" 115712Ssam #include "../h/mbuf.h" 125712Ssam #include "../net/in.h" 135712Ssam #include "../net/in_systm.h" 145712Ssam #include "../net/if_imp.h" 155860Sroot #include "../net/if_imphost.h" 165712Ssam 175712Ssam /* 185712Ssam * Head of host table hash chains. 195712Ssam */ 205860Sroot struct mbuf *hosts; 215712Ssam 225712Ssam /* 235712Ssam * Given an internet address 245712Ssam * return a host structure (if it exists). 255712Ssam */ 265712Ssam struct host * 275771Swnj hostlookup(addr) 285712Ssam struct in_addr addr; 295712Ssam { 305712Ssam register struct host *hp; 315712Ssam register struct mbuf *m; 325712Ssam register int hash = HOSTHASH(addr); 335712Ssam 345771Swnj COUNT(HOSTLOOKUP); 35*6089Sroot addr.s_lh = 0; 365860Sroot for (m = hosts; m; m = m->m_next) { 375712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 385712Ssam if (hp->h_refcnt == 0) 395860Sroot continue; 40*6089Sroot if (hp->h_addr.s_addr == addr.s_addr) 415712Ssam return (hp); 425712Ssam } 435712Ssam return (0); 445712Ssam } 455712Ssam 465712Ssam /* 475712Ssam * Enter a reference to this host's internet 485712Ssam * address. If no host structure exists, create 495712Ssam * one and hook it into the host database. 505712Ssam */ 515712Ssam struct host * 525771Swnj hostenter(addr) 535712Ssam struct in_addr addr; 545712Ssam { 555860Sroot register struct mbuf *m, **mprev; 565860Sroot register struct host *hp, *hp0 = 0; 575712Ssam register int hash = HOSTHASH(addr); 585712Ssam 595771Swnj COUNT(HOSTENTER); 60*6089Sroot addr.s_lh = 0; 615860Sroot mprev = &hosts; 625860Sroot while (m = *mprev) { 635712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 645860Sroot if (hp->h_refcnt == 0) { 655860Sroot if (hp0 == 0) 665860Sroot hp0 = hp; 675860Sroot continue; 685860Sroot } 695712Ssam if (hp->h_addr.s_addr == addr.s_addr) 705712Ssam goto foundhost; 715860Sroot mprev = &m->m_next; 725712Ssam } 735712Ssam 745712Ssam /* 755712Ssam * No current host structure, make one. 765712Ssam * If our search ran off the end of the 775712Ssam * chain of mbuf's, allocate another. 785712Ssam */ 795860Sroot if (hp0 == 0) { 805712Ssam m = m_getclr(M_DONTWAIT); 815712Ssam if (m == 0) 825712Ssam return (0); 835860Sroot *mprev = m; 845860Sroot m->m_off = MMINOFF; 855860Sroot hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 865712Ssam } 875860Sroot mtod(dtom(hp0), struct hmbuf *)->hm_count++; 885860Sroot hp = hp0; 895712Ssam hp->h_addr = addr; 905924Sroot hp->h_qcnt = 0; 915712Ssam 925712Ssam foundhost: 935712Ssam hp->h_refcnt++; /* know new structures have 0 val */ 945712Ssam return (hp); 955712Ssam } 965712Ssam 975712Ssam /* 985712Ssam * Free a reference to a host. If this causes the 995712Ssam * host structure to be released do so. 1005712Ssam */ 1015860Sroot hostfree(hp) 1025860Sroot register struct host *hp; 1035712Ssam { 1045712Ssam register struct mbuf *m; 1055712Ssam 1065771Swnj COUNT(HOSTFREE); 1075860Sroot if (--hp->h_refcnt) 1085860Sroot return; 1095860Sroot hostrelease(hp); 1105712Ssam } 1115712Ssam 1125712Ssam /* 1135712Ssam * Reset a given network's host entries. 1145712Ssam * This involves clearing all packet queue's 1155712Ssam * and releasing host structures. 1165712Ssam */ 1175771Swnj hostreset(net) 1185712Ssam int net; 1195712Ssam { 1205712Ssam register struct mbuf *m; 1215712Ssam register struct host *hp, *lp; 1225860Sroot struct hmbuf *hm; 1235860Sroot int x; 1245712Ssam 1255771Swnj COUNT(HOSTRESET); 1265860Sroot x = splimp(); 1275860Sroot for (m = hosts; m; m = m->m_next) { 1285860Sroot hm = mtod(m, struct hmbuf *); 1295860Sroot hp = hm->hm_hosts; 1305712Ssam lp = hp + HPMBUF; 1315860Sroot while (hm->hm_count != 0 && hp < lp) { 132*6089Sroot if (hp->h_addr.s_net == net) { 133*6089Sroot hp->h_refcnt = 0; 1345771Swnj hostrelease(mtod(m, struct hmbuf *), hp); 135*6089Sroot } 1365712Ssam hp++; 1375712Ssam } 1385712Ssam } 1395860Sroot splx(x); 1405712Ssam } 1415712Ssam 1425712Ssam /* 1435712Ssam * Remove a host structure and release 1445712Ssam * any resources it's accumulated. 1455712Ssam */ 1465860Sroot hostrelease(hp) 1475712Ssam register struct host *hp; 1485712Ssam { 1495860Sroot register struct mbuf *m, **mprev, *mh = dtom(hp); 1505712Ssam 1515771Swnj COUNT(HOSTRELEASE); 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 } 1655860Sroot if (--mtod(mh, struct hmbuf *)->hm_count) 1665712Ssam return; 1675860Sroot mprev = &hosts; 1685860Sroot while ((m = *mprev) != mh) 1695860Sroot mprev = &m->m_next; 1705860Sroot *mprev = mh->m_next; 1715860Sroot (void) m_free(mh); 1725712Ssam } 1735924Sroot 1745924Sroot /* 1755924Sroot * Remove a packet from the holding q. 1765924Sroot * The RFNM counter is also bumped. 1775924Sroot */ 1785924Sroot struct mbuf * 1795924Sroot hostdeque(hp) 1805924Sroot register struct host *hp; 1815924Sroot { 1825924Sroot register struct mbuf *m; 1835924Sroot 1845924Sroot hp->h_rfnm--; 1855924Sroot HOST_DEQUE(hp, m); 1865924Sroot if (m) 1875924Sroot return (m); 1885924Sroot if (hp->h_rfnm == 0) 1895924Sroot hostfree(hp); 1905924Sroot return (0); 1915924Sroot } 192