1*6589Ssam /* if_imphost.c 4.10 82/04/25 */ 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); 33*6589Ssam int s = splnet(); 345712Ssam 355771Swnj COUNT(HOSTLOOKUP); 365860Sroot for (m = hosts; m; m = m->m_next) { 375712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 38*6589Ssam if (hp->h_addr.s_addr == addr.s_addr) { 39*6589Ssam hp->h_flags |= HF_INUSE; 40*6589Ssam goto found; 41*6589Ssam } 425712Ssam } 43*6589Ssam hp = 0; 44*6589Ssam found: 45*6589Ssam splx(s); 46*6589Ssam return (hp); 475712Ssam } 485712Ssam 495712Ssam /* 505712Ssam * Enter a reference to this host's internet 515712Ssam * address. If no host structure exists, create 525712Ssam * one and hook it into the host database. 535712Ssam */ 545712Ssam struct host * 555771Swnj hostenter(addr) 565712Ssam struct in_addr addr; 575712Ssam { 585860Sroot register struct mbuf *m, **mprev; 595860Sroot register struct host *hp, *hp0 = 0; 605712Ssam register int hash = HOSTHASH(addr); 61*6589Ssam int s = splnet(); 625712Ssam 635771Swnj COUNT(HOSTENTER); 645860Sroot mprev = &hosts; 655860Sroot while (m = *mprev) { 666209Swnj mprev = &m->m_next; 675712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 68*6589Ssam if ((hp->h_flags & HF_INUSE) == 0) { 69*6589Ssam if (hp->h_addr.s_addr == addr.s_addr) 70*6589Ssam goto foundhost; 715860Sroot if (hp0 == 0) 725860Sroot hp0 = hp; 735860Sroot continue; 745860Sroot } 755712Ssam if (hp->h_addr.s_addr == addr.s_addr) 765712Ssam goto foundhost; 775712Ssam } 785712Ssam 795712Ssam /* 805712Ssam * No current host structure, make one. 815712Ssam * If our search ran off the end of the 825712Ssam * chain of mbuf's, allocate another. 835712Ssam */ 845860Sroot if (hp0 == 0) { 855712Ssam m = m_getclr(M_DONTWAIT); 86*6589Ssam if (m == 0) { 87*6589Ssam splx(s); 885712Ssam return (0); 89*6589Ssam } 905860Sroot *mprev = m; 915860Sroot m->m_off = MMINOFF; 925860Sroot hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 935712Ssam } 945860Sroot mtod(dtom(hp0), struct hmbuf *)->hm_count++; 955860Sroot hp = hp0; 965712Ssam hp->h_addr = addr; 97*6589Ssam hp->h_timer = 0; 985712Ssam 995712Ssam foundhost: 100*6589Ssam hp->h_flags |= HF_INUSE; 101*6589Ssam splx(s); 1025712Ssam return (hp); 1035712Ssam } 1045712Ssam 1055712Ssam /* 106*6589Ssam * Mark a host structure free and set it's 107*6589Ssam * timer going. 1085712Ssam */ 1095860Sroot hostfree(hp) 1105860Sroot register struct host *hp; 1115712Ssam { 112*6589Ssam int s = splnet(); 113*6589Ssam 1145771Swnj COUNT(HOSTFREE); 115*6589Ssam hp->h_flags &= ~HF_INUSE; 116*6589Ssam hp->h_timer = HOSTTIMER; 117*6589Ssam hp->h_rfnm = 0; 118*6589Ssam splx(s); 1195712Ssam } 1205712Ssam 1215712Ssam /* 1225712Ssam * Reset a given network's host entries. 1235712Ssam */ 1245771Swnj hostreset(net) 1255712Ssam int net; 1265712Ssam { 1275712Ssam register struct mbuf *m; 1285712Ssam register struct host *hp, *lp; 1295860Sroot struct hmbuf *hm; 130*6589Ssam int s = splnet(); 1315712Ssam 1325771Swnj COUNT(HOSTRESET); 1335860Sroot for (m = hosts; m; m = m->m_next) { 1345860Sroot hm = mtod(m, struct hmbuf *); 1355860Sroot hp = hm->hm_hosts; 1365712Ssam lp = hp + HPMBUF; 137*6589Ssam while (hm->hm_count > 0 && hp < lp) { 1386089Sroot if (hp->h_addr.s_net == net) { 139*6589Ssam hp->h_flags &= ~HF_INUSE; 1406145Ssam hostrelease(hp); 1416089Sroot } 1425712Ssam hp++; 1435712Ssam } 1445712Ssam } 145*6589Ssam splx(s); 1465712Ssam } 1475712Ssam 1485712Ssam /* 1495712Ssam * Remove a host structure and release 1505712Ssam * any resources it's accumulated. 151*6589Ssam * This routine is always called at splnet. 1525712Ssam */ 1535860Sroot hostrelease(hp) 1545712Ssam register struct host *hp; 1555712Ssam { 1565860Sroot register struct mbuf *m, **mprev, *mh = dtom(hp); 1575712Ssam 1585771Swnj COUNT(HOSTRELEASE); 1595712Ssam /* 1605712Ssam * Discard any packets left on the waiting q 1615712Ssam */ 1625771Swnj if (m = hp->h_q) { 1635868Sroot register struct mbuf *n; 1645868Sroot 1655868Sroot do { 1665868Sroot n = m->m_act; 1675868Sroot m_freem(m); 1685868Sroot m = n; 1695868Sroot } while (m != hp->h_q); 1705771Swnj hp->h_q = 0; 1715712Ssam } 1725860Sroot if (--mtod(mh, struct hmbuf *)->hm_count) 1735712Ssam return; 1745860Sroot mprev = &hosts; 1755860Sroot while ((m = *mprev) != mh) 1765860Sroot mprev = &m->m_next; 177*6589Ssam *mprev = m_free(mh); 1785712Ssam } 1795924Sroot 1805924Sroot /* 1815924Sroot * Remove a packet from the holding q. 1825924Sroot * The RFNM counter is also bumped. 1835924Sroot */ 1845924Sroot struct mbuf * 1855924Sroot hostdeque(hp) 1865924Sroot register struct host *hp; 1875924Sroot { 1885924Sroot register struct mbuf *m; 1895924Sroot 1905924Sroot hp->h_rfnm--; 1915924Sroot HOST_DEQUE(hp, m); 1925924Sroot if (m) 1935924Sroot return (m); 1945924Sroot if (hp->h_rfnm == 0) 1955924Sroot hostfree(hp); 1965924Sroot return (0); 1975924Sroot } 198*6589Ssam 199*6589Ssam /* 200*6589Ssam * Host data base timer routine. 201*6589Ssam * Decrement timers on structures which are 202*6589Ssam * waiting to be deallocated. On expiration 203*6589Ssam * release resources, possibly deallocating 204*6589Ssam * mbuf associated with structure. 205*6589Ssam */ 206*6589Ssam hostslowtimo() 207*6589Ssam { 208*6589Ssam register struct mbuf *m; 209*6589Ssam register struct host *hp, *lp; 210*6589Ssam struct hmbuf *hm; 211*6589Ssam int s = splnet(); 212*6589Ssam 213*6589Ssam COUNT(HOSTSLOWTIMO); 214*6589Ssam for (m = hosts; m; m = m->m_next) { 215*6589Ssam hm = mtod(m, struct hmbuf *); 216*6589Ssam hp = hm->hm_hosts; 217*6589Ssam lp = hp + HPMBUF; 218*6589Ssam while (hm->hm_count > 0 && hp < lp) { 219*6589Ssam if (hp->h_flags & HF_INUSE) 220*6589Ssam continue; 221*6589Ssam if (hp->h_timer && --hp->h_timer == 0) 222*6589Ssam hostrelease(hp); 223*6589Ssam hp++; 224*6589Ssam } 225*6589Ssam } 226*6589Ssam splx(s); 227*6589Ssam } 228