aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/x25_in.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/x25/x25_in.c')
-rw-r--r--net/x25/x25_in.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c
index 63488fd4885a..a49cd4ec551a 100644
--- a/net/x25/x25_in.c
+++ b/net/x25/x25_in.c
@@ -107,6 +107,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
107 /* 107 /*
108 * Parse the data in the frame. 108 * Parse the data in the frame.
109 */ 109 */
110 if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
111 goto out_clear;
110 skb_pull(skb, X25_STD_MIN_LEN); 112 skb_pull(skb, X25_STD_MIN_LEN);
111 113
112 len = x25_parse_address_block(skb, &source_addr, 114 len = x25_parse_address_block(skb, &source_addr,
@@ -130,9 +132,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
130 if (skb->len > X25_MAX_CUD_LEN) 132 if (skb->len > X25_MAX_CUD_LEN)
131 goto out_clear; 133 goto out_clear;
132 134
133 skb_copy_from_linear_data(skb, 135 skb_copy_bits(skb, 0, x25->calluserdata.cuddata,
134 x25->calluserdata.cuddata, 136 skb->len);
135 skb->len);
136 x25->calluserdata.cudlength = skb->len; 137 x25->calluserdata.cudlength = skb->len;
137 } 138 }
138 if (!sock_flag(sk, SOCK_DEAD)) 139 if (!sock_flag(sk, SOCK_DEAD))
@@ -140,6 +141,9 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
140 break; 141 break;
141 } 142 }
142 case X25_CLEAR_REQUEST: 143 case X25_CLEAR_REQUEST:
144 if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
145 goto out_clear;
146
143 x25_write_internal(sk, X25_CLEAR_CONFIRMATION); 147 x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
144 x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]); 148 x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
145 break; 149 break;
@@ -167,6 +171,9 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp
167 switch (frametype) { 171 switch (frametype) {
168 172
169 case X25_CLEAR_REQUEST: 173 case X25_CLEAR_REQUEST:
174 if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
175 goto out_clear;
176
170 x25_write_internal(sk, X25_CLEAR_CONFIRMATION); 177 x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
171 x25_disconnect(sk, 0, skb->data[3], skb->data[4]); 178 x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
172 break; 179 break;
@@ -180,6 +187,11 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp
180 } 187 }
181 188
182 return 0; 189 return 0;
190
191out_clear:
192 x25_write_internal(sk, X25_CLEAR_REQUEST);
193 x25_start_t23timer(sk);
194 return 0;
183} 195}
184 196
185/* 197/*
@@ -209,6 +221,9 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
209 break; 221 break;
210 222
211 case X25_CLEAR_REQUEST: 223 case X25_CLEAR_REQUEST:
224 if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
225 goto out_clear;
226
212 x25_write_internal(sk, X25_CLEAR_CONFIRMATION); 227 x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
213 x25_disconnect(sk, 0, skb->data[3], skb->data[4]); 228 x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
214 break; 229 break;
@@ -307,6 +322,12 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
307 } 322 }
308 323
309 return queued; 324 return queued;
325
326out_clear:
327 x25_write_internal(sk, X25_CLEAR_REQUEST);
328 x25->state = X25_STATE_2;
329 x25_start_t23timer(sk);
330 return 0;
310} 331}
311 332
312/* 333/*
@@ -316,13 +337,13 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
316 */ 337 */
317static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype) 338static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype)
318{ 339{
340 struct x25_sock *x25 = x25_sk(sk);
341
319 switch (frametype) { 342 switch (frametype) {
320 343
321 case X25_RESET_REQUEST: 344 case X25_RESET_REQUEST:
322 x25_write_internal(sk, X25_RESET_CONFIRMATION); 345 x25_write_internal(sk, X25_RESET_CONFIRMATION);
323 case X25_RESET_CONFIRMATION: { 346 case X25_RESET_CONFIRMATION: {
324 struct x25_sock *x25 = x25_sk(sk);
325
326 x25_stop_timer(sk); 347 x25_stop_timer(sk);
327 x25->condition = 0x00; 348 x25->condition = 0x00;
328 x25->va = 0; 349 x25->va = 0;
@@ -334,6 +355,9 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
334 break; 355 break;
335 } 356 }
336 case X25_CLEAR_REQUEST: 357 case X25_CLEAR_REQUEST:
358 if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
359 goto out_clear;
360
337 x25_write_internal(sk, X25_CLEAR_CONFIRMATION); 361 x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
338 x25_disconnect(sk, 0, skb->data[3], skb->data[4]); 362 x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
339 break; 363 break;
@@ -343,6 +367,12 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
343 } 367 }
344 368
345 return 0; 369 return 0;
370
371out_clear:
372 x25_write_internal(sk, X25_CLEAR_REQUEST);
373 x25->state = X25_STATE_2;
374 x25_start_t23timer(sk);
375 return 0;
346} 376}
347 377
348/* Higher level upcall for a LAPB frame */ 378/* Higher level upcall for a LAPB frame */