1 /* if_imphost.c 4.8 82/03/15 */ 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 mprev = &m->m_next; 64 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 65 if (hp->h_refcnt == 0) { 66 if (hp0 == 0) 67 hp0 = hp; 68 continue; 69 } 70 if (hp->h_addr.s_addr == addr.s_addr) 71 goto foundhost; 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 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 hp->h_refcnt = 0; 132 hostrelease(hp); 133 } 134 hp++; 135 } 136 } 137 splx(x); 138 } 139 140 /* 141 * Remove a host structure and release 142 * any resources it's accumulated. 143 */ 144 hostrelease(hp) 145 register struct host *hp; 146 { 147 register struct mbuf *m, **mprev, *mh = dtom(hp); 148 149 COUNT(HOSTRELEASE); 150 /* 151 * Discard any packets left on the waiting q 152 */ 153 if (m = hp->h_q) { 154 register struct mbuf *n; 155 156 do { 157 n = m->m_act; 158 m_freem(m); 159 m = n; 160 } while (m != hp->h_q); 161 hp->h_q = 0; 162 } 163 if (--mtod(mh, struct hmbuf *)->hm_count) 164 return; 165 mprev = &hosts; 166 while ((m = *mprev) != mh) 167 mprev = &m->m_next; 168 *mprev = mh->m_next; 169 (void) m_free(mh); 170 } 171 172 /* 173 * Remove a packet from the holding q. 174 * The RFNM counter is also bumped. 175 */ 176 struct mbuf * 177 hostdeque(hp) 178 register struct host *hp; 179 { 180 register struct mbuf *m; 181 182 hp->h_rfnm--; 183 HOST_DEQUE(hp, m); 184 if (m) 185 return (m); 186 if (hp->h_rfnm == 0) 187 hostfree(hp); 188 return (0); 189 } 190