1*23168Smckusick /* 2*23168Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23168Smckusick * All rights reserved. The Berkeley software License Agreement 4*23168Smckusick * specifies the terms and conditions for redistribution. 5*23168Smckusick * 6*23168Smckusick * @(#)if_imphost.c 6.4 (Berkeley) 06/08/85 7*23168Smckusick */ 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" 2111231Ssam 228412Swnj #include "../netinet/in.h" 238412Swnj #include "../netinet/in_systm.h" 2411231Ssam 2517069Sbloom #include "if_imp.h" 2617069Sbloom #include "if_imphost.h" 275712Ssam 285712Ssam /* 295712Ssam * Head of host table hash chains. 305712Ssam */ 315860Sroot struct mbuf *hosts; 325712Ssam 335712Ssam /* 345712Ssam * Given an internet address 355712Ssam * return a host structure (if it exists). 365712Ssam */ 375712Ssam struct host * 385771Swnj hostlookup(addr) 395712Ssam struct in_addr addr; 405712Ssam { 415712Ssam register struct host *hp; 425712Ssam register struct mbuf *m; 435712Ssam register int hash = HOSTHASH(addr); 445712Ssam 455860Sroot for (m = hosts; m; m = m->m_next) { 465712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 476589Ssam if (hp->h_addr.s_addr == addr.s_addr) { 486589Ssam hp->h_flags |= HF_INUSE; 4911231Ssam return (hp); 506589Ssam } 515712Ssam } 5211231Ssam return ((struct host *)0); 535712Ssam } 545712Ssam 555712Ssam /* 565712Ssam * Enter a reference to this host's internet 575712Ssam * address. If no host structure exists, create 585712Ssam * one and hook it into the host database. 595712Ssam */ 605712Ssam struct host * 615771Swnj hostenter(addr) 625712Ssam struct in_addr addr; 635712Ssam { 645860Sroot register struct mbuf *m, **mprev; 655860Sroot register struct host *hp, *hp0 = 0; 665712Ssam register int hash = HOSTHASH(addr); 675712Ssam 685860Sroot mprev = &hosts; 695860Sroot while (m = *mprev) { 706209Swnj mprev = &m->m_next; 715712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 726589Ssam if ((hp->h_flags & HF_INUSE) == 0) { 736589Ssam if (hp->h_addr.s_addr == addr.s_addr) 746589Ssam goto foundhost; 755860Sroot if (hp0 == 0) 765860Sroot hp0 = hp; 775860Sroot continue; 785860Sroot } 795712Ssam if (hp->h_addr.s_addr == addr.s_addr) 805712Ssam goto foundhost; 815712Ssam } 825712Ssam 835712Ssam /* 845712Ssam * No current host structure, make one. 855712Ssam * If our search ran off the end of the 865712Ssam * chain of mbuf's, allocate another. 875712Ssam */ 885860Sroot if (hp0 == 0) { 899646Ssam m = m_getclr(M_DONTWAIT, MT_HTABLE); 9011231Ssam if (m == NULL) 9111231Ssam return ((struct host *)0); 925860Sroot *mprev = m; 935860Sroot hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 945712Ssam } 955860Sroot mtod(dtom(hp0), struct hmbuf *)->hm_count++; 965860Sroot hp = hp0; 975712Ssam hp->h_addr = addr; 986589Ssam hp->h_timer = 0; 996725Ssam hp->h_flags = 0; 1005712Ssam 1015712Ssam foundhost: 1026589Ssam hp->h_flags |= HF_INUSE; 1035712Ssam return (hp); 1045712Ssam } 1055712Ssam 1065712Ssam /* 1076589Ssam * Mark a host structure free and set it's 1086589Ssam * timer going. 1095712Ssam */ 1105860Sroot hostfree(hp) 1115860Sroot register struct host *hp; 1125712Ssam { 1136589Ssam 1146589Ssam hp->h_flags &= ~HF_INUSE; 1156589Ssam hp->h_timer = HOSTTIMER; 1166589Ssam hp->h_rfnm = 0; 1175712Ssam } 1185712Ssam 1195712Ssam /* 1205712Ssam * Reset a given network's host entries. 1215712Ssam */ 1225771Swnj hostreset(net) 12318133Skarels long net; 1245712Ssam { 1255712Ssam register struct mbuf *m; 1265712Ssam register struct host *hp, *lp; 1275860Sroot struct hmbuf *hm; 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) { 13418133Skarels if (in_netof(hp->h_addr) == net) { 1356589Ssam hp->h_flags &= ~HF_INUSE; 1366145Ssam hostrelease(hp); 1376089Sroot } 1385712Ssam hp++; 1395712Ssam } 1405712Ssam } 1415712Ssam } 1425712Ssam 1435712Ssam /* 1445712Ssam * Remove a host structure and release 1455712Ssam * any resources it's accumulated. 1465712Ssam */ 1475860Sroot hostrelease(hp) 1485712Ssam register struct host *hp; 1495712Ssam { 1505860Sroot register struct mbuf *m, **mprev, *mh = dtom(hp); 1515712Ssam 1525712Ssam /* 1535712Ssam * Discard any packets left on the waiting q 1545712Ssam */ 1555771Swnj if (m = hp->h_q) { 1565868Sroot register struct mbuf *n; 1575868Sroot 1585868Sroot do { 1595868Sroot n = m->m_act; 1605868Sroot m_freem(m); 1615868Sroot m = n; 1625868Sroot } while (m != hp->h_q); 1635771Swnj hp->h_q = 0; 1645712Ssam } 1656725Ssam hp->h_flags = 0; 16618133Skarels hp->h_rfnm = 0; 1675860Sroot if (--mtod(mh, struct hmbuf *)->hm_count) 1685712Ssam return; 1695860Sroot mprev = &hosts; 1705860Sroot while ((m = *mprev) != mh) 1715860Sroot mprev = &m->m_next; 1726589Ssam *mprev = m_free(mh); 1735712Ssam } 1745924Sroot 1755924Sroot /* 1765924Sroot * Remove a packet from the holding q. 1775924Sroot * The RFNM counter is also bumped. 1785924Sroot */ 1795924Sroot struct mbuf * 1805924Sroot hostdeque(hp) 1815924Sroot register struct host *hp; 1825924Sroot { 1835924Sroot register struct mbuf *m; 1845924Sroot 1855924Sroot hp->h_rfnm--; 1865924Sroot HOST_DEQUE(hp, m); 1875924Sroot if (m) 1885924Sroot return (m); 1895924Sroot if (hp->h_rfnm == 0) 1905924Sroot hostfree(hp); 1915924Sroot return (0); 1925924Sroot } 1936589Ssam 1946589Ssam /* 1956589Ssam * Host data base timer routine. 1966589Ssam * Decrement timers on structures which are 1976589Ssam * waiting to be deallocated. On expiration 1986589Ssam * release resources, possibly deallocating 1996589Ssam * mbuf associated with structure. 2006589Ssam */ 2016589Ssam hostslowtimo() 2026589Ssam { 2036589Ssam register struct mbuf *m; 2046589Ssam register struct host *hp, *lp; 2056589Ssam struct hmbuf *hm; 20611231Ssam int s = splimp(); 2076589Ssam 2086589Ssam for (m = hosts; m; m = m->m_next) { 2096589Ssam hm = mtod(m, struct hmbuf *); 2106589Ssam hp = hm->hm_hosts; 2116589Ssam lp = hp + HPMBUF; 2126779Ssam for (; hm->hm_count > 0 && hp < lp; hp++) { 2136589Ssam if (hp->h_flags & HF_INUSE) 2146589Ssam continue; 2156589Ssam if (hp->h_timer && --hp->h_timer == 0) 2166589Ssam hostrelease(hp); 2176589Ssam } 2186589Ssam } 21911241Ssam splx(s); 2206589Ssam } 22113081Ssam #endif 222