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