1 /**************************************************************************/ 2 /* */ 3 /* HMP protocol: see RFC 869, Dec. 1983 for details */ 4 /* original version by Craig Partridge (craig@bbn-unix) */ 5 /* January 1985 */ 6 /* */ 7 /**************************************************************************/ 8 9 #ifdef HMP 10 11 #include "../h/param.h" 12 #include "../h/dir.h" 13 #include "../h/user.h" 14 #include "../h/mbuf.h" 15 #include "../h/protosw.h" 16 #include "../h/socket.h" 17 #include "../h/socketvar.h" 18 #include "../h/errno.h" 19 20 #include "../net/if.h" 21 #include "../net/route.h" 22 23 #include "../bbnnet/in.h" 24 #include "../bbnnet/in_pcb.h" 25 #include "../bbnnet/in_var.h" 26 #include "../bbnnet/ip.h" 27 #include "../bbnnet/hmp.h" 28 #include "../bbnnet/hmp_var.h" 29 30 extern hmp_binding_used(); 31 32 struct pr_advice hmp_advice = 33 { 34 HM_MAXPORTS, 35 HM_MAXPORTS, 36 HM_MAXPORTS, 37 HM_MAXPORTS, 38 sizeof(u_char), 39 hmp_binding_used, 40 } ; 41 42 /**************************************************************************/ 43 /* */ 44 /* generate a new HMP inpcb */ 45 /* */ 46 /**************************************************************************/ 47 48 hmp_attach(so,head) 49 struct socket *so; 50 struct inpcb *head; 51 { 52 register struct inpcb *inp; 53 register struct mbuf *m; 54 register struct hmpcb *hp; 55 int error = 0; 56 57 if (!(error = soreserve(so,2048,2048))) 58 { 59 if (!(error = in_pcballoc(so,head))) 60 { 61 inp = sotoinpcb(so); 62 inp->inp_lport = inp->inp_fport = 0; 63 64 if ((m = m_getclr(M_WAIT,MT_PCB)) != (struct mbuf *)0) 65 { 66 hp = mtod(m,struct hmpcb *); 67 inp->inp_ppcb = (caddr_t) hp; 68 return(0); 69 } 70 error = ENOBUFS; 71 in_pcbdetach(inp); 72 } 73 } 74 75 return(error); 76 } 77 78 /**************************************************************************/ 79 /* */ 80 /* get rid of a no longer used HMP inpcb */ 81 /* */ 82 /**************************************************************************/ 83 84 hmp_detach(inp) 85 register struct inpcb *inp; 86 { 87 register struct hmpcb *hp; 88 register int error; 89 90 if (inp == (struct inpcb *)0) 91 error = ENOTCONN; 92 else 93 { 94 error = 0; 95 hp = intohmpcb(inp); 96 (void) m_free(dtom(hp)); 97 inp->inp_ppcb = (caddr_t)0; 98 99 in_pcbdetach(inp); 100 } 101 return(error); 102 } 103 104 /**************************************************************************/ 105 /* */ 106 /**************************************************************************/ 107 108 int hmp_binding_used(inp, lport, lsaddr, reuselocal) 109 struct inpcb *inp; 110 u_short lport; 111 u_long lsaddr; 112 { 113 register struct inpcb *i; 114 115 if (reuselocal) 116 return(1); 117 118 for (i = hmp.inp_next; i != &hmp; i = i->inp_next) 119 { 120 /* don't want to find ourself */ 121 if ((i != inp) && (i->inp_lport == lport)) 122 if ((i->inp_laddr.s_addr == lsaddr) || 123 (i->inp_laddr.s_addr == INADDR_ANY) || 124 (lsaddr == INADDR_ANY)) 125 break; 126 } 127 return (i != &hmp); 128 } 129 130 /**************************************************************************/ 131 /* */ 132 /* binds and stuffs all hmp garbage into its pcb */ 133 /* */ 134 /**************************************************************************/ 135 136 hmp_bind(inp,nam) 137 struct inpcb *inp; 138 struct mbuf *nam; 139 { 140 int error; 141 142 register struct hmpcb *hp = intohmpcb(inp); 143 register struct sockaddr_hmp *sinh; 144 145 sinh = mtod(nam,struct sockaddr_hmp *); 146 147 if (error = in_pcbbind(inp,nam,&hmp_advice)) 148 return(error); 149 150 /* now do hmp stuff */ 151 152 hp->hp_inpcb = inp; 153 hp->hp_lsystyp = sinh->sih_systype; 154 hp->hp_lmsgtyp = sinh->sih_msgtype; 155 hp->hp_lseq = sinh->sih_seqno; 156 hp->hp_lpasswd = sinh->sih_passwd; 157 hp->hp_flags = sinh->sih_options & (HM_BINDOPTS); 158 159 return(0); 160 } 161 162 /**************************************************************************/ 163 /* */ 164 /* connect to remote end. All this does is semi-permanently set the */ 165 /* destination address..... */ 166 /* */ 167 /**************************************************************************/ 168 169 hmp_connect(inp,nam) 170 struct inpcb *inp; 171 struct mbuf *nam; 172 { 173 register struct socket *so = inp->inp_socket; 174 register struct sockaddr_hmp *sinh; 175 register struct hmpcb *hp; 176 register int error = 0; 177 178 if (inp->inp_faddr.s_addr != INADDR_ANY) 179 return(EISCONN); 180 181 /* not bound? */ 182 if (inp->inp_lport==0) 183 { 184 if (error = in_pcbbind(inp,(struct mbuf *)0),&hmp_advice) 185 return(error); 186 } 187 188 if ((nam == (struct mbuf *)0) || (nam->m_len != sizeof(*sinh))) 189 return(EINVAL); 190 191 sinh = mtod(nam,struct sockaddr_hmp *); 192 193 if ((sinh->sin_port & 0xff) != sinh->sin_port) 194 return(EINVAL); 195 196 inp->inp_fport = sinh->sin_port; 197 inp->inp_faddr = sinh->sin_addr; 198 199 /* now do hmp stuff */ 200 201 hp = intohmpcb(inp); 202 203 hp->hp_rsystyp = sinh->sih_systype; 204 hp->hp_rmsgtyp = sinh->sih_msgtype; 205 hp->hp_rseq = sinh->sih_seqno; 206 hp->hp_rpasswd = sinh->sih_passwd; 207 hp->hp_ctlflg = sinh->sih_ctlflgs; 208 hp->hp_flags = sinh->sih_options & HM_CONNOPTS; 209 210 return(0); 211 } 212 213 /**************************************************************************/ 214 /* */ 215 /* break association with a remote address */ 216 /* */ 217 /**************************************************************************/ 218 219 hmp_disconnect(inp) 220 register struct inpcb *inp; 221 { 222 register struct hmpcb *hp; 223 224 if (inp->inp_faddr.s_addr == INADDR_ANY) 225 return(ENOTCONN); 226 227 hp = intohmpcb(inp); 228 229 /* clean up the hmpcb */ 230 231 hp->hp_rsystyp = 0; 232 hp->hp_rmsgtyp = 0; 233 hp->hp_rseq = 0; 234 hp->hp_rpasswd = 0; 235 hp->hp_ctlflg = 0; 236 hp->hp_flags &= ~HM_CONNOPTS; 237 238 in_pcbdisconnect(inp); 239 240 return(0); 241 } 242 #endif HMP 243