1 /* if_imphost.c 4.5 82/02/21 */ 2 3 #include "imp.h" 4 #if NIMP > 0 5 /* 6 * Host table manipulation routines. 7 * Only needed when shipping stuff through an IMP. 8 */ 9 10 #include "../h/param.h" 11 #include "../h/mbuf.h" 12 #include "../net/in.h" 13 #include "../net/in_systm.h" 14 #include "../net/if_imp.h" 15 #include "../net/if_imphost.h" 16 17 /* 18 * Head of host table hash chains. 19 */ 20 struct mbuf *hosts; 21 22 /* 23 * Given an internet address 24 * return a host structure (if it exists). 25 */ 26 struct host * 27 hostlookup(addr) 28 struct in_addr addr; 29 { 30 register struct host *hp; 31 register struct mbuf *m; 32 register int hash = HOSTHASH(addr); 33 34 COUNT(HOSTLOOKUP); 35 for (m = hosts; m; m = m->m_next) { 36 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 37 if (hp->h_refcnt == 0) 38 continue; 39 if (hp->h_addr.s_addr == addr.s_addr) 40 return (hp); 41 } 42 return (0); 43 } 44 45 /* 46 * Enter a reference to this host's internet 47 * address. If no host structure exists, create 48 * one and hook it into the host database. 49 */ 50 struct host * 51 hostenter(addr) 52 struct in_addr addr; 53 { 54 register struct mbuf *m, **mprev; 55 register struct host *hp, *hp0 = 0; 56 register int hash = HOSTHASH(addr); 57 58 COUNT(HOSTENTER); 59 mprev = &hosts; 60 while (m = *mprev) { 61 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 62 if (hp->h_refcnt == 0) { 63 if (hp0 == 0) 64 hp0 = hp; 65 continue; 66 } 67 if (hp->h_addr.s_addr == addr.s_addr) 68 goto foundhost; 69 mprev = &m->m_next; 70 } 71 72 /* 73 * No current host structure, make one. 74 * If our search ran off the end of the 75 * chain of mbuf's, allocate another. 76 */ 77 if (hp0 == 0) { 78 m = m_getclr(M_DONTWAIT); 79 if (m == 0) 80 return (0); 81 *mprev = m; 82 m->m_off = MMINOFF; 83 hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 84 } 85 mtod(dtom(hp0), struct hmbuf *)->hm_count++; 86 hp = hp0; 87 hp->h_addr = addr; 88 hp->h_qcnt = 0; 89 90 foundhost: 91 hp->h_refcnt++; /* know new structures have 0 val */ 92 return (hp); 93 } 94 95 /* 96 * Free a reference to a host. If this causes the 97 * host structure to be released do so. 98 */ 99 hostfree(hp) 100 register struct host *hp; 101 { 102 register struct mbuf *m; 103 104 COUNT(HOSTFREE); 105 if (--hp->h_refcnt) 106 return; 107 hostrelease(hp); 108 } 109 110 /* 111 * Reset a given network's host entries. 112 * This involves clearing all packet queue's 113 * and releasing host structures. 114 */ 115 hostreset(net) 116 int net; 117 { 118 register struct mbuf *m; 119 register struct host *hp, *lp; 120 struct hmbuf *hm; 121 int x; 122 123 COUNT(HOSTRESET); 124 x = splimp(); 125 for (m = hosts; m; m = m->m_next) { 126 hm = mtod(m, struct hmbuf *); 127 hp = hm->hm_hosts; 128 lp = hp + HPMBUF; 129 while (hm->hm_count != 0 && hp < lp) { 130 if (hp->h_addr.s_net == net) 131 hostrelease(mtod(m, struct hmbuf *), hp); 132 hp++; 133 } 134 } 135 splx(x); 136 } 137 138 /* 139 * Remove a host structure and release 140 * any resources it's accumulated. 141 */ 142 hostrelease(hp) 143 register struct host *hp; 144 { 145 register struct mbuf *m, **mprev, *mh = dtom(hp); 146 147 COUNT(HOSTRELEASE); 148 /* 149 * Discard any packets left on the waiting q 150 */ 151 if (m = hp->h_q) { 152 register struct mbuf *n; 153 154 do { 155 n = m->m_act; 156 m_freem(m); 157 m = n; 158 } while (m != hp->h_q); 159 hp->h_q = 0; 160 } 161 if (--mtod(mh, struct hmbuf *)->hm_count) 162 return; 163 mprev = &hosts; 164 while ((m = *mprev) != mh) 165 mprev = &m->m_next; 166 *mprev = mh->m_next; 167 (void) m_free(mh); 168 } 169 170 /* 171 * Remove a packet from the holding q. 172 * The RFNM counter is also bumped. 173 */ 174 struct mbuf * 175 hostdeque(hp) 176 register struct host *hp; 177 { 178 register struct mbuf *m; 179 180 hp->h_rfnm--; 181 HOST_DEQUE(hp, m); 182 if (m) 183 return (m); 184 if (hp->h_rfnm == 0) 185 hostfree(hp); 186 return (0); 187 } 188