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
hmp_detach(inp)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
hmp_binding_used(inp,lport,lsaddr,reuselocal)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
hmp_disconnect(inp)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