1*8412Swnj /* if_imphost.c 4.15 82/10/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" 12*8412Swnj #include "../netinet/in.h" 13*8412Swnj #include "../netinet/in_systm.h" 14*8412Swnj #include "../netimp/if_imp.h" 15*8412Swnj #include "../netimp/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); 336589Ssam int s = splnet(); 345712Ssam 355860Sroot for (m = hosts; m; m = m->m_next) { 365712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 376589Ssam if (hp->h_addr.s_addr == addr.s_addr) { 386589Ssam hp->h_flags |= HF_INUSE; 396589Ssam goto found; 406589Ssam } 415712Ssam } 426589Ssam hp = 0; 436589Ssam found: 446589Ssam splx(s); 456589Ssam return (hp); 465712Ssam } 475712Ssam 485712Ssam /* 495712Ssam * Enter a reference to this host's internet 505712Ssam * address. If no host structure exists, create 515712Ssam * one and hook it into the host database. 525712Ssam */ 535712Ssam struct host * 545771Swnj hostenter(addr) 555712Ssam struct in_addr addr; 565712Ssam { 575860Sroot register struct mbuf *m, **mprev; 585860Sroot register struct host *hp, *hp0 = 0; 595712Ssam register int hash = HOSTHASH(addr); 606589Ssam int s = splnet(); 615712Ssam 625860Sroot mprev = &hosts; 635860Sroot while (m = *mprev) { 646209Swnj mprev = &m->m_next; 655712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 666589Ssam if ((hp->h_flags & HF_INUSE) == 0) { 676589Ssam if (hp->h_addr.s_addr == addr.s_addr) 686589Ssam goto foundhost; 695860Sroot if (hp0 == 0) 705860Sroot hp0 = hp; 715860Sroot continue; 725860Sroot } 735712Ssam if (hp->h_addr.s_addr == addr.s_addr) 745712Ssam goto foundhost; 755712Ssam } 765712Ssam 775712Ssam /* 785712Ssam * No current host structure, make one. 795712Ssam * If our search ran off the end of the 805712Ssam * chain of mbuf's, allocate another. 815712Ssam */ 825860Sroot if (hp0 == 0) { 835712Ssam m = m_getclr(M_DONTWAIT); 846589Ssam if (m == 0) { 856589Ssam splx(s); 865712Ssam return (0); 876589Ssam } 885860Sroot *mprev = m; 895860Sroot hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 905712Ssam } 915860Sroot mtod(dtom(hp0), struct hmbuf *)->hm_count++; 925860Sroot hp = hp0; 935712Ssam hp->h_addr = addr; 946589Ssam hp->h_timer = 0; 956725Ssam hp->h_flags = 0; 965712Ssam 975712Ssam foundhost: 986589Ssam hp->h_flags |= HF_INUSE; 996589Ssam splx(s); 1005712Ssam return (hp); 1015712Ssam } 1025712Ssam 1035712Ssam /* 1046589Ssam * Mark a host structure free and set it's 1056589Ssam * timer going. 1065712Ssam */ 1075860Sroot hostfree(hp) 1085860Sroot register struct host *hp; 1095712Ssam { 1106589Ssam int s = splnet(); 1116589Ssam 1126589Ssam hp->h_flags &= ~HF_INUSE; 1136589Ssam hp->h_timer = HOSTTIMER; 1146589Ssam hp->h_rfnm = 0; 1156589Ssam splx(s); 1165712Ssam } 1175712Ssam 1185712Ssam /* 1195712Ssam * Reset a given network's host entries. 1205712Ssam */ 1215771Swnj hostreset(net) 1225712Ssam int net; 1235712Ssam { 1245712Ssam register struct mbuf *m; 1255712Ssam register struct host *hp, *lp; 1265860Sroot struct hmbuf *hm; 1276589Ssam int s = splnet(); 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) { 1346089Sroot if (hp->h_addr.s_net == net) { 1356589Ssam hp->h_flags &= ~HF_INUSE; 1366145Ssam hostrelease(hp); 1376089Sroot } 1385712Ssam hp++; 1395712Ssam } 1405712Ssam } 1416589Ssam splx(s); 1425712Ssam } 1435712Ssam 1445712Ssam /* 1455712Ssam * Remove a host structure and release 1465712Ssam * any resources it's accumulated. 1476589Ssam * This routine is always called at splnet. 1485712Ssam */ 1495860Sroot hostrelease(hp) 1505712Ssam register struct host *hp; 1515712Ssam { 1525860Sroot register struct mbuf *m, **mprev, *mh = dtom(hp); 1535712Ssam 1545712Ssam /* 1555712Ssam * Discard any packets left on the waiting q 1565712Ssam */ 1575771Swnj if (m = hp->h_q) { 1585868Sroot register struct mbuf *n; 1595868Sroot 1605868Sroot do { 1615868Sroot n = m->m_act; 1625868Sroot m_freem(m); 1635868Sroot m = n; 1645868Sroot } while (m != hp->h_q); 1655771Swnj hp->h_q = 0; 1665712Ssam } 1676725Ssam hp->h_flags = 0; 1685860Sroot if (--mtod(mh, struct hmbuf *)->hm_count) 1695712Ssam return; 1705860Sroot mprev = &hosts; 1715860Sroot while ((m = *mprev) != mh) 1725860Sroot mprev = &m->m_next; 1736589Ssam *mprev = m_free(mh); 1745712Ssam } 1755924Sroot 1765924Sroot /* 1775924Sroot * Remove a packet from the holding q. 1785924Sroot * The RFNM counter is also bumped. 1795924Sroot */ 1805924Sroot struct mbuf * 1815924Sroot hostdeque(hp) 1825924Sroot register struct host *hp; 1835924Sroot { 1845924Sroot register struct mbuf *m; 1855924Sroot 1865924Sroot hp->h_rfnm--; 1875924Sroot HOST_DEQUE(hp, m); 1885924Sroot if (m) 1895924Sroot return (m); 1905924Sroot if (hp->h_rfnm == 0) 1915924Sroot hostfree(hp); 1925924Sroot return (0); 1935924Sroot } 1946589Ssam 1956589Ssam /* 1966589Ssam * Host data base timer routine. 1976589Ssam * Decrement timers on structures which are 1986589Ssam * waiting to be deallocated. On expiration 1996589Ssam * release resources, possibly deallocating 2006589Ssam * mbuf associated with structure. 2016589Ssam */ 2026589Ssam hostslowtimo() 2036589Ssam { 2046589Ssam register struct mbuf *m; 2056589Ssam register struct host *hp, *lp; 2066589Ssam struct hmbuf *hm; 2076589Ssam int s = splnet(); 2086589Ssam 2096589Ssam for (m = hosts; m; m = m->m_next) { 2106589Ssam hm = mtod(m, struct hmbuf *); 2116589Ssam hp = hm->hm_hosts; 2126589Ssam lp = hp + HPMBUF; 2136779Ssam for (; hm->hm_count > 0 && hp < lp; hp++) { 2146589Ssam if (hp->h_flags & HF_INUSE) 2156589Ssam continue; 2166589Ssam if (hp->h_timer && --hp->h_timer == 0) 2176589Ssam hostrelease(hp); 2186589Ssam } 2196589Ssam } 2206589Ssam splx(s); 2216589Ssam } 222