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