1*5860Sroot /* if_imphost.c 4.3 82/02/16 */ 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" 15*5860Sroot #include "../net/if_imphost.h" 165712Ssam 175712Ssam /* 185712Ssam * Head of host table hash chains. 195712Ssam */ 20*5860Sroot 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*5860Sroot for (m = hosts; m; m = m->m_next) { 365712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 375712Ssam if (hp->h_refcnt == 0) 38*5860Sroot continue; 395712Ssam if (hp->h_addr.s_addr == addr.s_addr) 405712Ssam return (hp); 415712Ssam } 425712Ssam return (0); 435712Ssam } 445712Ssam 455712Ssam /* 465712Ssam * Enter a reference to this host's internet 475712Ssam * address. If no host structure exists, create 485712Ssam * one and hook it into the host database. 495712Ssam */ 505712Ssam struct host * 515771Swnj hostenter(addr) 525712Ssam struct in_addr addr; 535712Ssam { 54*5860Sroot register struct mbuf *m, **mprev; 55*5860Sroot register struct host *hp, *hp0 = 0; 565712Ssam register int hash = HOSTHASH(addr); 575712Ssam 585771Swnj COUNT(HOSTENTER); 59*5860Sroot mprev = &hosts; 60*5860Sroot while (m = *mprev) { 615712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 62*5860Sroot if (hp->h_refcnt == 0) { 63*5860Sroot if (hp0 == 0) 64*5860Sroot hp0 = hp; 65*5860Sroot continue; 66*5860Sroot } 675712Ssam if (hp->h_addr.s_addr == addr.s_addr) 685712Ssam goto foundhost; 69*5860Sroot mprev = &m->m_next; 705712Ssam } 715712Ssam 725712Ssam /* 735712Ssam * No current host structure, make one. 745712Ssam * If our search ran off the end of the 755712Ssam * chain of mbuf's, allocate another. 765712Ssam */ 77*5860Sroot if (hp0 == 0) { 785712Ssam m = m_getclr(M_DONTWAIT); 795712Ssam if (m == 0) 805712Ssam return (0); 81*5860Sroot *mprev = m; 82*5860Sroot m->m_off = MMINOFF; 83*5860Sroot hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 845712Ssam } 85*5860Sroot mtod(dtom(hp0), struct hmbuf *)->hm_count++; 86*5860Sroot hp = hp0; 875712Ssam hp->h_addr = addr; 885712Ssam hp->h_status = HOSTS_UP; 895712Ssam 905712Ssam foundhost: 915712Ssam hp->h_refcnt++; /* know new structures have 0 val */ 925712Ssam return (hp); 935712Ssam } 945712Ssam 955712Ssam /* 965712Ssam * Free a reference to a host. If this causes the 975712Ssam * host structure to be released do so. 985712Ssam */ 99*5860Sroot hostfree(hp) 100*5860Sroot register struct host *hp; 1015712Ssam { 1025712Ssam register struct mbuf *m; 1035712Ssam 1045771Swnj COUNT(HOSTFREE); 105*5860Sroot if (--hp->h_refcnt) 106*5860Sroot return; 107*5860Sroot hostrelease(hp); 1085712Ssam } 1095712Ssam 1105712Ssam /* 1115712Ssam * Reset a given network's host entries. 1125712Ssam * This involves clearing all packet queue's 1135712Ssam * and releasing host structures. 1145712Ssam */ 1155771Swnj hostreset(net) 1165712Ssam int net; 1175712Ssam { 1185712Ssam register struct mbuf *m; 1195712Ssam register struct host *hp, *lp; 120*5860Sroot struct hmbuf *hm; 121*5860Sroot int x; 1225712Ssam 1235771Swnj COUNT(HOSTRESET); 124*5860Sroot x = splimp(); 125*5860Sroot for (m = hosts; m; m = m->m_next) { 126*5860Sroot hm = mtod(m, struct hmbuf *); 127*5860Sroot hp = hm->hm_hosts; 1285712Ssam lp = hp + HPMBUF; 129*5860Sroot while (hm->hm_count != 0 && hp < lp) { 1305712Ssam if (hp->h_addr.s_net == net) 1315771Swnj hostrelease(mtod(m, struct hmbuf *), hp); 1325712Ssam hp++; 1335712Ssam } 1345712Ssam } 135*5860Sroot splx(x); 1365712Ssam } 1375712Ssam 1385712Ssam /* 1395712Ssam * Remove a host structure and release 1405712Ssam * any resources it's accumulated. 1415712Ssam */ 142*5860Sroot hostrelease(hp) 1435712Ssam register struct host *hp; 1445712Ssam { 145*5860Sroot register struct mbuf *m, **mprev, *mh = dtom(hp); 1465712Ssam 1475771Swnj COUNT(HOSTRELEASE); 1485712Ssam /* 1495712Ssam * Discard any packets left on the waiting q 1505712Ssam */ 1515771Swnj if (m = hp->h_q) { 1525771Swnj m = m->m_next; 1535771Swnj hp->h_q->m_next = 0; 1545771Swnj hp->h_q = 0; 1555712Ssam m_freem(m); 1565712Ssam } 157*5860Sroot if (--mtod(mh, struct hmbuf *)->hm_count) 1585712Ssam return; 159*5860Sroot mprev = &hosts; 160*5860Sroot while ((m = *mprev) != mh) 161*5860Sroot mprev = &m->m_next; 162*5860Sroot *mprev = mh->m_next; 163*5860Sroot (void) m_free(mh); 1645712Ssam } 165