mac80211 & nl80211: add support to abort a scan request on tx
[linux-2.6.git] / net / x25 / x25_subr.c
index 352b32d..5170d52 100644 (file)
@@ -23,6 +23,7 @@
  *                                             restriction on response.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/skbuff.h>
@@ -125,32 +126,30 @@ void x25_write_internal(struct sock *sk, int frametype)
         *      Adjust frame size.
         */
        switch (frametype) {
-               case X25_CALL_REQUEST:
-                       len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN +
-                              X25_MAX_CUD_LEN;
-                       break;
-               case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */
-                       if(x25->facilities.reverse & 0x80) {
-                               len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
-                       } else {
-                               len += 1 + X25_MAX_FAC_LEN;
-                       }
-                       break;
-               case X25_CLEAR_REQUEST:
-               case X25_RESET_REQUEST:
-                       len += 2;
-                       break;
-               case X25_RR:
-               case X25_RNR:
-               case X25_REJ:
-               case X25_CLEAR_CONFIRMATION:
-               case X25_INTERRUPT_CONFIRMATION:
-               case X25_RESET_CONFIRMATION:
-                       break;
-               default:
-                       printk(KERN_ERR "X.25: invalid frame type %02X\n",
-                              frametype);
-                       return;
+       case X25_CALL_REQUEST:
+               len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
+               break;
+       case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */
+               if (x25->facilities.reverse & 0x80) {
+                       len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
+               } else {
+                       len += 1 + X25_MAX_FAC_LEN;
+               }
+               break;
+       case X25_CLEAR_REQUEST:
+       case X25_RESET_REQUEST:
+               len += 2;
+               break;
+       case X25_RR:
+       case X25_RNR:
+       case X25_REJ:
+       case X25_CLEAR_CONFIRMATION:
+       case X25_INTERRUPT_CONFIRMATION:
+       case X25_RESET_CONFIRMATION:
+               break;
+       default:
+               printk(KERN_ERR "X.25: invalid frame type %02X\n", frametype);
+               return;
        }
 
        if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
@@ -270,31 +269,39 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
               int *d, int *m)
 {
        struct x25_sock *x25 = x25_sk(sk);
-       unsigned char *frame = skb->data;
+       unsigned char *frame;
+
+       if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+               return X25_ILLEGAL;
+       frame = skb->data;
 
        *ns = *nr = *q = *d = *m = 0;
 
        switch (frame[2]) {
-               case X25_CALL_REQUEST:
-               case X25_CALL_ACCEPTED:
-               case X25_CLEAR_REQUEST:
-               case X25_CLEAR_CONFIRMATION:
-               case X25_INTERRUPT:
-               case X25_INTERRUPT_CONFIRMATION:
-               case X25_RESET_REQUEST:
-               case X25_RESET_CONFIRMATION:
-               case X25_RESTART_REQUEST:
-               case X25_RESTART_CONFIRMATION:
-               case X25_REGISTRATION_REQUEST:
-               case X25_REGISTRATION_CONFIRMATION:
-               case X25_DIAGNOSTIC:
-                       return frame[2];
+       case X25_CALL_REQUEST:
+       case X25_CALL_ACCEPTED:
+       case X25_CLEAR_REQUEST:
+       case X25_CLEAR_CONFIRMATION:
+       case X25_INTERRUPT:
+       case X25_INTERRUPT_CONFIRMATION:
+       case X25_RESET_REQUEST:
+       case X25_RESET_CONFIRMATION:
+       case X25_RESTART_REQUEST:
+       case X25_RESTART_CONFIRMATION:
+       case X25_REGISTRATION_REQUEST:
+       case X25_REGISTRATION_CONFIRMATION:
+       case X25_DIAGNOSTIC:
+               return frame[2];
        }
 
        if (x25->neighbour->extended) {
                if (frame[2] == X25_RR  ||
                    frame[2] == X25_RNR ||
                    frame[2] == X25_REJ) {
+                       if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
+                               return X25_ILLEGAL;
+                       frame = skb->data;
+
                        *nr = (frame[3] >> 1) & 0x7F;
                        return frame[2];
                }
@@ -309,6 +316,10 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
 
        if (x25->neighbour->extended) {
                if ((frame[2] & 0x01) == X25_DATA) {
+                       if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
+                               return X25_ILLEGAL;
+                       frame = skb->data;
+
                        *q  = (frame[0] & X25_Q_BIT) == X25_Q_BIT;
                        *d  = (frame[0] & X25_D_BIT) == X25_D_BIT;
                        *m  = (frame[3] & X25_EXT_M_BIT) == X25_EXT_M_BIT;