123168Smckusick /* 223168Smckusick * Copyright (c) 1982 Regents of the University of California. 323168Smckusick * All rights reserved. The Berkeley software License Agreement 423168Smckusick * specifies the terms and conditions for redistribution. 523168Smckusick * 6*24778Skarels * @(#)if_imphost.c 6.5 (Berkeley) 09/16/85 723168Smckusick */ 85712Ssam 95712Ssam #include "imp.h" 105712Ssam #if NIMP > 0 115712Ssam /* 125712Ssam * Host table manipulation routines. 135712Ssam * Only needed when shipping stuff through an IMP. 1411231Ssam * 1511231Ssam * Everything in here is called at splimp from 1611231Ssam * from the IMP protocol code (if_imp.c), or 1711231Ssam * interlocks with the code at splimp. 185712Ssam */ 1917069Sbloom #include "param.h" 2017069Sbloom #include "mbuf.h" 21*24778Skarels #include "syslog.h" 2211231Ssam 238412Swnj #include "../netinet/in.h" 248412Swnj #include "../netinet/in_systm.h" 2511231Ssam 2617069Sbloom #include "if_imp.h" 2717069Sbloom #include "if_imphost.h" 285712Ssam 295712Ssam /* 305712Ssam * Head of host table hash chains. 315712Ssam */ 325860Sroot struct mbuf *hosts; 335712Ssam 345712Ssam /* 355712Ssam * Given an internet address 365712Ssam * return a host structure (if it exists). 375712Ssam */ 385712Ssam struct host * 395771Swnj hostlookup(addr) 405712Ssam struct in_addr addr; 415712Ssam { 425712Ssam register struct host *hp; 435712Ssam register struct mbuf *m; 445712Ssam register int hash = HOSTHASH(addr); 455712Ssam 465860Sroot for (m = hosts; m; m = m->m_next) { 475712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 486589Ssam if (hp->h_addr.s_addr == addr.s_addr) { 496589Ssam hp->h_flags |= HF_INUSE; 5011231Ssam return (hp); 516589Ssam } 525712Ssam } 5311231Ssam return ((struct host *)0); 545712Ssam } 555712Ssam 565712Ssam /* 575712Ssam * Enter a reference to this host's internet 585712Ssam * address. If no host structure exists, create 595712Ssam * one and hook it into the host database. 605712Ssam */ 615712Ssam struct host * 625771Swnj hostenter(addr) 635712Ssam struct in_addr addr; 645712Ssam { 655860Sroot register struct mbuf *m, **mprev; 665860Sroot register struct host *hp, *hp0 = 0; 675712Ssam register int hash = HOSTHASH(addr); 685712Ssam 695860Sroot mprev = &hosts; 705860Sroot while (m = *mprev) { 716209Swnj mprev = &m->m_next; 725712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 736589Ssam if ((hp->h_flags & HF_INUSE) == 0) { 746589Ssam if (hp->h_addr.s_addr == addr.s_addr) 756589Ssam goto foundhost; 765860Sroot if (hp0 == 0) 775860Sroot hp0 = hp; 785860Sroot continue; 795860Sroot } 805712Ssam if (hp->h_addr.s_addr == addr.s_addr) 815712Ssam goto foundhost; 825712Ssam } 835712Ssam 845712Ssam /* 855712Ssam * No current host structure, make one. 865712Ssam * If our search ran off the end of the 875712Ssam * chain of mbuf's, allocate another. 885712Ssam */ 895860Sroot if (hp0 == 0) { 909646Ssam m = m_getclr(M_DONTWAIT, MT_HTABLE); 9111231Ssam if (m == NULL) 9211231Ssam return ((struct host *)0); 935860Sroot *mprev = m; 945860Sroot hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 955712Ssam } 965860Sroot mtod(dtom(hp0), struct hmbuf *)->hm_count++; 975860Sroot hp = hp0; 985712Ssam hp->h_addr = addr; 996589Ssam hp->h_timer = 0; 1006725Ssam hp->h_flags = 0; 1015712Ssam 1025712Ssam foundhost: 1036589Ssam hp->h_flags |= HF_INUSE; 1045712Ssam return (hp); 1055712Ssam } 1065712Ssam 1075712Ssam /* 1086589Ssam * Mark a host structure free and set it's 1096589Ssam * timer going. 1105712Ssam */ 1115860Sroot hostfree(hp) 1125860Sroot register struct host *hp; 1135712Ssam { 1146589Ssam 1156589Ssam hp->h_flags &= ~HF_INUSE; 1166589Ssam hp->h_timer = HOSTTIMER; 1176589Ssam hp->h_rfnm = 0; 1185712Ssam } 1195712Ssam 1205712Ssam /* 1215712Ssam * Reset a given network's host entries. 1225712Ssam */ 1235771Swnj hostreset(net) 124*24778Skarels u_long net; 1255712Ssam { 1265712Ssam register struct mbuf *m; 1275712Ssam register struct host *hp, *lp; 1285860Sroot struct hmbuf *hm; 129*24778Skarels struct mbuf *mnext; 1305712Ssam 131*24778Skarels for (m = hosts; m; m = mnext) { 132*24778Skarels mnext = m->m_next; 1335860Sroot hm = mtod(m, struct hmbuf *); 1345860Sroot hp = hm->hm_hosts; 1355712Ssam lp = hp + HPMBUF; 1366589Ssam while (hm->hm_count > 0 && hp < lp) { 13718133Skarels if (in_netof(hp->h_addr) == net) { 1386589Ssam hp->h_flags &= ~HF_INUSE; 1396145Ssam hostrelease(hp); 1406089Sroot } 1415712Ssam hp++; 1425712Ssam } 1435712Ssam } 1445712Ssam } 1455712Ssam 1465712Ssam /* 1475712Ssam * Remove a host structure and release 1485712Ssam * any resources it's accumulated. 1495712Ssam */ 1505860Sroot hostrelease(hp) 1515712Ssam register struct host *hp; 1525712Ssam { 1535860Sroot register struct mbuf *m, **mprev, *mh = dtom(hp); 1545712Ssam 1555712Ssam /* 1565712Ssam * Discard any packets left on the waiting q 1575712Ssam */ 1585771Swnj if (m = hp->h_q) { 1595868Sroot register struct mbuf *n; 1605868Sroot 1615868Sroot do { 1625868Sroot n = m->m_act; 1635868Sroot m_freem(m); 1645868Sroot m = n; 1655868Sroot } while (m != hp->h_q); 1665771Swnj hp->h_q = 0; 1675712Ssam } 1686725Ssam hp->h_flags = 0; 16918133Skarels hp->h_rfnm = 0; 1705860Sroot if (--mtod(mh, struct hmbuf *)->hm_count) 1715712Ssam return; 1725860Sroot mprev = &hosts; 1735860Sroot while ((m = *mprev) != mh) 1745860Sroot mprev = &m->m_next; 1756589Ssam *mprev = m_free(mh); 1765712Ssam } 1775924Sroot 1785924Sroot /* 1795924Sroot * Remove a packet from the holding q. 1805924Sroot * The RFNM counter is also bumped. 1815924Sroot */ 1825924Sroot struct mbuf * 1835924Sroot hostdeque(hp) 1845924Sroot register struct host *hp; 1855924Sroot { 1865924Sroot register struct mbuf *m; 1875924Sroot 1885924Sroot hp->h_rfnm--; 1895924Sroot HOST_DEQUE(hp, m); 1905924Sroot if (m) 1915924Sroot return (m); 1925924Sroot if (hp->h_rfnm == 0) 1935924Sroot hostfree(hp); 1945924Sroot return (0); 1955924Sroot } 1966589Ssam 1976589Ssam /* 1986589Ssam * Host data base timer routine. 1996589Ssam * Decrement timers on structures which are 2006589Ssam * waiting to be deallocated. On expiration 2016589Ssam * release resources, possibly deallocating 2026589Ssam * mbuf associated with structure. 2036589Ssam */ 2046589Ssam hostslowtimo() 2056589Ssam { 2066589Ssam register struct mbuf *m; 2076589Ssam register struct host *hp, *lp; 2086589Ssam struct hmbuf *hm; 209*24778Skarels struct mbuf *mnext; 21011231Ssam int s = splimp(); 2116589Ssam 212*24778Skarels for (m = hosts; m; m = mnext) { 213*24778Skarels mnext = m->m_next; 2146589Ssam hm = mtod(m, struct hmbuf *); 2156589Ssam hp = hm->hm_hosts; 2166589Ssam lp = hp + HPMBUF; 2176779Ssam for (; hm->hm_count > 0 && hp < lp; hp++) { 218*24778Skarels if (hp->h_timer && --hp->h_timer == 0) { 219*24778Skarels if (hp->h_rfnm) 220*24778Skarels log(KERN_RECOV, 221*24778Skarels "imp?: host %x, lost %d rfnms\n", 222*24778Skarels ntohs(hp->h_addr.s_addr), hp->h_rfnm); 2236589Ssam hostrelease(hp); 224*24778Skarels } 2256589Ssam } 2266589Ssam } 22711241Ssam splx(s); 2286589Ssam } 22913081Ssam #endif 230