1 /* if_imphost.c 4.1 82/02/06 */ 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/host.h" 15 #include "../net/if_imp.h" 16 17 /* 18 * Head of host table hash chains. 19 */ 20 struct mbuf hosttable = { 0, MMINOFF }; 21 22 /* 23 * Given an internet address 24 * return a host structure (if it exists). 25 */ 26 struct host * 27 h_lookup(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(H_LOOKUP); 35 printf("h_lookup(%x)\n", addr); 36 for (m = &hosttable; m; m = m->m_next) { 37 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 38 if (hp->h_refcnt == 0) 39 break; 40 printf("h_lookup: addr=%x\n", hp->h_addr.s_addr); 41 if (hp->h_addr.s_addr == addr.s_addr) 42 return (hp); 43 } 44 return (0); 45 } 46 47 /* 48 * Enter a reference to this host's internet 49 * address. If no host structure exists, create 50 * one and hook it into the host database. 51 */ 52 struct host * 53 h_enter(addr) 54 struct in_addr addr; 55 { 56 register struct mbuf *m, *mprev; 57 register struct host *hp; 58 register int hash = HOSTHASH(addr); 59 60 COUNT(H_ENTER); 61 printf("h_enter(%x)\n", addr); 62 for (m = &hosttable; m; mprev = m, m = m->m_next) { 63 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 64 if (hp->h_refcnt == 0) 65 break; 66 printf("h_enter: addr=%x\n", addr); 67 if (hp->h_addr.s_addr == addr.s_addr) 68 goto foundhost; 69 } 70 71 /* 72 * No current host structure, make one. 73 * If our search ran off the end of the 74 * chain of mbuf's, allocate another. 75 */ 76 printf("h_enter: new host\n"); 77 if (m == 0) { 78 m = m_getclr(M_DONTWAIT); 79 if (m == 0) 80 return (0); 81 mprev->m_next = m; 82 m->m_act = mprev; 83 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 84 } 85 mtod(m, struct hmbuf *)->hm_count++; 86 hp->h_addr = addr; 87 hp->h_status = HOSTS_UP; 88 89 foundhost: 90 hp->h_refcnt++; /* know new structures have 0 val */ 91 return (hp); 92 } 93 94 /* 95 * Free a reference to a host. If this causes the 96 * host structure to be released do so. 97 */ 98 h_free(addr) 99 struct in_addr addr; 100 { 101 register struct mbuf *m; 102 register struct host *hp; 103 register int hash = HOSTHASH(addr); 104 105 COUNT(H_FREE); 106 printf("h_free(%x)\n", addr); 107 for (m = &hosttable; m; m = m->m_next) { 108 hp = &mtod(m, struct hmbuf *)->hm_hosts[hash]; 109 if (hp->h_refcnt == 0) 110 return; 111 if (hp->h_addr.s_addr == addr.s_addr) { 112 if (--hp->h_refcnt == 0) 113 h_release(mtod(m, struct hmbuf *), hp); 114 return; 115 } 116 } 117 panic("h_free"); 118 } 119 120 /* 121 * Reset a given network's host entries. 122 * This involves clearing all packet queue's 123 * and releasing host structures. 124 */ 125 h_reset(net) 126 int net; 127 { 128 register struct mbuf *m; 129 register struct host *hp, *lp; 130 131 COUNT(H_RESET); 132 printf("h_reset(%x)\n", net); 133 for (m = &hosttable; m; m = m->m_next) { 134 hp = mtod(m, struct hmbuf *)->hm_hosts; 135 lp = hp + HPMBUF; 136 while (hp < lp) { 137 if (hp->h_addr.s_net == net) 138 h_release(mtod(m, struct hmbuf *), hp); 139 hp++; 140 } 141 } 142 } 143 144 /* 145 * Remove a host structure and release 146 * any resources it's accumulated. 147 */ 148 h_release(hm, hp) 149 struct hmbuf *hm; 150 register struct host *hp; 151 { 152 register struct mbuf *m; 153 154 COUNT(H_RELEASE); 155 printf("h_release(%x,%x)\n", hm, hp); 156 /* 157 * Discard any packets left on the waiting q 158 */ 159 while (m = hp->h_q) { 160 hp->h_q = m->m_act; 161 m_freem(m); 162 } 163 /* 164 * We could compact the database here, but is 165 * it worth it? For now we assume not and just 166 * handle the simple case. 167 */ 168 printf("h_releasse: count=%d\n", hm->h_count); 169 if (--hm->hm_count || (m = dtom(hm)) == &hosttable) 170 return; 171 m->m_act->m_next = m->m_next; 172 m->m_next->m_act = m->m_act; 173 m_freem(m); 174 } 175