123168Smckusick /* 229081Smckusick * Copyright (c) 1982, 1986 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*33427Skarels * @(#)if_imphost.c 7.2 (Berkeley) 02/03/88 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*33427Skarels #include "socket.h" 2224778Skarels #include "syslog.h" 2311231Ssam 24*33427Skarels #include "../net/if.h" 25*33427Skarels 268412Swnj #include "../netinet/in.h" 278412Swnj #include "../netinet/in_systm.h" 2811231Ssam 2917069Sbloom #include "if_imp.h" 3017069Sbloom #include "if_imphost.h" 315712Ssam 325712Ssam /* 335712Ssam * Head of host table hash chains. 345712Ssam */ 355860Sroot struct mbuf *hosts; 36*33427Skarels extern struct imp_softc imp_softc[]; 375712Ssam 385712Ssam /* 395712Ssam * Given an internet address 405712Ssam * return a host structure (if it exists). 415712Ssam */ 425712Ssam struct host * 43*33427Skarels hostlookup(imp, host, unit) 44*33427Skarels int imp, host, unit; 455712Ssam { 465712Ssam register struct host *hp; 475712Ssam register struct mbuf *m; 48*33427Skarels register int hash = HOSTHASH(imp, host); 495712Ssam 505860Sroot for (m = hosts; m; m = m->m_next) { 515712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 52*33427Skarels if (hp->h_imp == imp && hp->h_host == host && 53*33427Skarels hp->h_unit == unit) { 546589Ssam hp->h_flags |= HF_INUSE; 5511231Ssam return (hp); 566589Ssam } 575712Ssam } 5811231Ssam return ((struct host *)0); 595712Ssam } 605712Ssam 615712Ssam /* 625712Ssam * Enter a reference to this host's internet 635712Ssam * address. If no host structure exists, create 645712Ssam * one and hook it into the host database. 655712Ssam */ 665712Ssam struct host * 67*33427Skarels hostenter(imp, host, unit) 68*33427Skarels int imp, host, unit; 695712Ssam { 705860Sroot register struct mbuf *m, **mprev; 715860Sroot register struct host *hp, *hp0 = 0; 72*33427Skarels register int hash = HOSTHASH(imp, host); 735712Ssam 745860Sroot mprev = &hosts; 755860Sroot while (m = *mprev) { 766209Swnj mprev = &m->m_next; 775712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 78*33427Skarels if (hp->h_imp == imp && hp->h_host == host && 79*33427Skarels hp->h_unit == unit) 80*33427Skarels goto foundhost; 816589Ssam if ((hp->h_flags & HF_INUSE) == 0) { 825860Sroot if (hp0 == 0) 835860Sroot hp0 = hp; 845860Sroot continue; 855860Sroot } 865712Ssam } 875712Ssam 885712Ssam /* 895712Ssam * No current host structure, make one. 905712Ssam * If our search ran off the end of the 915712Ssam * chain of mbuf's, allocate another. 925712Ssam */ 935860Sroot if (hp0 == 0) { 949646Ssam m = m_getclr(M_DONTWAIT, MT_HTABLE); 9511231Ssam if (m == NULL) 9611231Ssam return ((struct host *)0); 975860Sroot *mprev = m; 985860Sroot hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 995712Ssam } 1005860Sroot mtod(dtom(hp0), struct hmbuf *)->hm_count++; 1015860Sroot hp = hp0; 102*33427Skarels hp->h_imp = imp; 103*33427Skarels hp->h_host = host; 104*33427Skarels hp->h_unit = unit; 1056589Ssam hp->h_timer = 0; 1066725Ssam hp->h_flags = 0; 1075712Ssam 1085712Ssam foundhost: 1096589Ssam hp->h_flags |= HF_INUSE; 1105712Ssam return (hp); 1115712Ssam } 1125712Ssam 1135712Ssam /* 114*33427Skarels * Reset a given imp unit's host entries. 1155712Ssam */ 116*33427Skarels hostreset(unit) 117*33427Skarels int unit; 1185712Ssam { 1195712Ssam register struct mbuf *m; 1205712Ssam register struct host *hp, *lp; 1215860Sroot struct hmbuf *hm; 1225712Ssam 123*33427Skarels 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) { 128*33427Skarels if (hp->h_unit == unit) 1296145Ssam hostrelease(hp); 1305712Ssam hp++; 1315712Ssam } 1325712Ssam } 133*33427Skarels hostcompress(); 1345712Ssam } 1355712Ssam 1365712Ssam /* 1375712Ssam * Remove a host structure and release 1385712Ssam * any resources it's accumulated. 1395712Ssam */ 1405860Sroot hostrelease(hp) 1415712Ssam register struct host *hp; 1425712Ssam { 1435860Sroot register struct mbuf *m, **mprev, *mh = dtom(hp); 1445712Ssam 1455712Ssam /* 1465712Ssam * Discard any packets left on the waiting q 1475712Ssam */ 1485771Swnj if (m = hp->h_q) { 1495868Sroot register struct mbuf *n; 1505868Sroot 1515868Sroot do { 1525868Sroot n = m->m_act; 1535868Sroot m_freem(m); 1545868Sroot m = n; 1555868Sroot } while (m != hp->h_q); 1565771Swnj hp->h_q = 0; 1575712Ssam } 1586725Ssam hp->h_flags = 0; 15918133Skarels hp->h_rfnm = 0; 160*33427Skarels --mtod(mh, struct hmbuf *)->hm_count; 1615712Ssam } 1625924Sroot 163*33427Skarels hostcompress() 1645924Sroot { 165*33427Skarels register struct mbuf *m, **mprev; 1665924Sroot 167*33427Skarels mprev = &hosts; 168*33427Skarels while (m = *mprev) { 169*33427Skarels if (mtod(m, struct hmbuf *)->hm_count == 0) 170*33427Skarels *mprev = m_free(m); 171*33427Skarels else 172*33427Skarels mprev = &m->m_next; 173*33427Skarels } 1745924Sroot } 1756589Ssam 1766589Ssam /* 1776589Ssam * Host data base timer routine. 1786589Ssam * Decrement timers on structures which are 1796589Ssam * waiting to be deallocated. On expiration 1806589Ssam * release resources, possibly deallocating 1816589Ssam * mbuf associated with structure. 1826589Ssam */ 1836589Ssam hostslowtimo() 1846589Ssam { 1856589Ssam register struct mbuf *m; 1866589Ssam register struct host *hp, *lp; 1876589Ssam struct hmbuf *hm; 188*33427Skarels int s = splimp(), any = 0; 1896589Ssam 190*33427Skarels for (m = hosts; m; m = m->m_next) { 1916589Ssam hm = mtod(m, struct hmbuf *); 1926589Ssam hp = hm->hm_hosts; 1936589Ssam lp = hp + HPMBUF; 1946779Ssam for (; hm->hm_count > 0 && hp < lp; hp++) { 195*33427Skarels if (hp->h_timer && --hp->h_timer == 0) { 196*33427Skarels if (hp->h_rfnm) { 197*33427Skarels log(LOG_WARNING, 198*33427Skarels "imp%d: host %d/imp %d, lost %d rfnms\n", 199*33427Skarels hp->h_unit, hp->h_host, ntohs(hp->h_imp), 200*33427Skarels hp->h_rfnm); 201*33427Skarels imp_softc[hp->h_unit].imp_lostrfnm += hp->h_rfnm; 202*33427Skarels hp->h_rfnm = 0; 203*33427Skarels if (hp->h_q) { 204*33427Skarels imprestarthost(hp); 205*33427Skarels continue; 206*33427Skarels } 20724778Skarels } 208*33427Skarels any = 1; 209*33427Skarels hostrelease(hp); 210*33427Skarels } 2116589Ssam } 2126589Ssam } 213*33427Skarels if (any) 214*33427Skarels hostcompress(); 21511241Ssam splx(s); 2166589Ssam } 21713081Ssam #endif 218