Commit | Line | Data |
---|---|---|
17efd7fe MK |
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 |