1*11231Ssam /* if_imphost.c 4.17 83/02/23 */ 25712Ssam 35712Ssam #include "imp.h" 45712Ssam #if NIMP > 0 55712Ssam /* 65712Ssam * Host table manipulation routines. 75712Ssam * Only needed when shipping stuff through an IMP. 8*11231Ssam * 9*11231Ssam * Everything in here is called at splimp from 10*11231Ssam * from the IMP protocol code (if_imp.c), or 11*11231Ssam * interlocks with the code at splimp. 125712Ssam */ 135712Ssam #include "../h/param.h" 145712Ssam #include "../h/mbuf.h" 15*11231Ssam 168412Swnj #include "../netinet/in.h" 178412Swnj #include "../netinet/in_systm.h" 18*11231Ssam 198412Swnj #include "../netimp/if_imp.h" 208412Swnj #include "../netimp/if_imphost.h" 215712Ssam 225712Ssam /* 235712Ssam * Head of host table hash chains. 245712Ssam */ 255860Sroot struct mbuf *hosts; 265712Ssam 275712Ssam /* 285712Ssam * Given an internet address 295712Ssam * return a host structure (if it exists). 305712Ssam */ 315712Ssam struct host * 325771Swnj hostlookup(addr) 335712Ssam struct in_addr addr; 345712Ssam { 355712Ssam register struct host *hp; 365712Ssam register struct mbuf *m; 375712Ssam register int hash = HOSTHASH(addr); 385712Ssam 395860Sroot for (m = hosts; m; m = m->m_next) { 405712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 416589Ssam if (hp->h_addr.s_addr == addr.s_addr) { 426589Ssam hp->h_flags |= HF_INUSE; 43*11231Ssam return (hp); 446589Ssam } 455712Ssam } 46*11231Ssam return ((struct host *)0); 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); 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) { 839646Ssam m = m_getclr(M_DONTWAIT, MT_HTABLE); 84*11231Ssam if (m == NULL) 85*11231Ssam return ((struct host *)0); 865860Sroot *mprev = m; 875860Sroot hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 885712Ssam } 895860Sroot mtod(dtom(hp0), struct hmbuf *)->hm_count++; 905860Sroot hp = hp0; 915712Ssam hp->h_addr = addr; 926589Ssam hp->h_timer = 0; 936725Ssam hp->h_flags = 0; 945712Ssam 955712Ssam foundhost: 966589Ssam hp->h_flags |= HF_INUSE; 975712Ssam return (hp); 985712Ssam } 995712Ssam 1005712Ssam /* 1016589Ssam * Mark a host structure free and set it's 1026589Ssam * timer going. 1035712Ssam */ 1045860Sroot hostfree(hp) 1055860Sroot register struct host *hp; 1065712Ssam { 1076589Ssam 1086589Ssam hp->h_flags &= ~HF_INUSE; 1096589Ssam hp->h_timer = HOSTTIMER; 1106589Ssam hp->h_rfnm = 0; 1115712Ssam } 1125712Ssam 1135712Ssam /* 1145712Ssam * Reset a given network's host entries. 1155712Ssam */ 1165771Swnj hostreset(net) 1175712Ssam int net; 1185712Ssam { 1195712Ssam register struct mbuf *m; 1205712Ssam register struct host *hp, *lp; 1215860Sroot struct hmbuf *hm; 1225712Ssam 1235860Sroot for (m = hosts; m; m = m->m_next) { 1245860Sroot hm = mtod(m, struct hmbuf *); 1255860Sroot hp = hm->hm_hosts; 1265712Ssam lp = hp + HPMBUF; 1276589Ssam while (hm->hm_count > 0 && hp < lp) { 1286089Sroot if (hp->h_addr.s_net == net) { 1296589Ssam hp->h_flags &= ~HF_INUSE; 1306145Ssam hostrelease(hp); 1316089Sroot } 1325712Ssam hp++; 1335712Ssam } 1345712Ssam } 1355712Ssam } 1365712Ssam 1375712Ssam /* 1385712Ssam * Remove a host structure and release 1395712Ssam * any resources it's accumulated. 1405712Ssam */ 1415860Sroot hostrelease(hp) 1425712Ssam register struct host *hp; 1435712Ssam { 1445860Sroot register struct mbuf *m, **mprev, *mh = dtom(hp); 1455712Ssam 1465712Ssam /* 1475712Ssam * Discard any packets left on the waiting q 1485712Ssam */ 1495771Swnj if (m = hp->h_q) { 1505868Sroot register struct mbuf *n; 1515868Sroot 1525868Sroot do { 1535868Sroot n = m->m_act; 1545868Sroot m_freem(m); 1555868Sroot m = n; 1565868Sroot } while (m != hp->h_q); 1575771Swnj hp->h_q = 0; 1585712Ssam } 1596725Ssam hp->h_flags = 0; 1605860Sroot if (--mtod(mh, struct hmbuf *)->hm_count) 1615712Ssam return; 1625860Sroot mprev = &hosts; 1635860Sroot while ((m = *mprev) != mh) 1645860Sroot mprev = &m->m_next; 1656589Ssam *mprev = m_free(mh); 1665712Ssam } 1675924Sroot 1685924Sroot /* 1695924Sroot * Remove a packet from the holding q. 1705924Sroot * The RFNM counter is also bumped. 1715924Sroot */ 1725924Sroot struct mbuf * 1735924Sroot hostdeque(hp) 1745924Sroot register struct host *hp; 1755924Sroot { 1765924Sroot register struct mbuf *m; 1775924Sroot 1785924Sroot hp->h_rfnm--; 1795924Sroot HOST_DEQUE(hp, m); 1805924Sroot if (m) 1815924Sroot return (m); 1825924Sroot if (hp->h_rfnm == 0) 1835924Sroot hostfree(hp); 1845924Sroot return (0); 1855924Sroot } 1866589Ssam 1876589Ssam /* 1886589Ssam * Host data base timer routine. 1896589Ssam * Decrement timers on structures which are 1906589Ssam * waiting to be deallocated. On expiration 1916589Ssam * release resources, possibly deallocating 1926589Ssam * mbuf associated with structure. 1936589Ssam */ 1946589Ssam hostslowtimo() 1956589Ssam { 1966589Ssam register struct mbuf *m; 1976589Ssam register struct host *hp, *lp; 1986589Ssam struct hmbuf *hm; 199*11231Ssam int s = splimp(); 2006589Ssam 2016589Ssam for (m = hosts; m; m = m->m_next) { 2026589Ssam hm = mtod(m, struct hmbuf *); 2036589Ssam hp = hm->hm_hosts; 2046589Ssam lp = hp + HPMBUF; 2056779Ssam for (; hm->hm_count > 0 && hp < lp; hp++) { 2066589Ssam if (hp->h_flags & HF_INUSE) 2076589Ssam continue; 2086589Ssam if (hp->h_timer && --hp->h_timer == 0) 2096589Ssam hostrelease(hp); 2106589Ssam } 2116589Ssam } 212*11231Ssam splimp(s); 2136589Ssam } 214