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