This source file includes following definitions.
- x25_pacsize_to_bytes
- x25_output
- x25_send_iframe
- x25_kick
- x25_enquiry_response
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 #include <linux/slab.h>
  21 #include <linux/socket.h>
  22 #include <linux/kernel.h>
  23 #include <linux/string.h>
  24 #include <linux/skbuff.h>
  25 #include <net/sock.h>
  26 #include <net/x25.h>
  27 
  28 static int x25_pacsize_to_bytes(unsigned int pacsize)
  29 {
  30         int bytes = 1;
  31 
  32         if (!pacsize)
  33                 return 128;
  34 
  35         while (pacsize-- > 0)
  36                 bytes *= 2;
  37 
  38         return bytes;
  39 }
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 int x25_output(struct sock *sk, struct sk_buff *skb)
  48 {
  49         struct sk_buff *skbn;
  50         unsigned char header[X25_EXT_MIN_LEN];
  51         int err, frontlen, len;
  52         int sent=0, noblock = X25_SKB_CB(skb)->flags & MSG_DONTWAIT;
  53         struct x25_sock *x25 = x25_sk(sk);
  54         int header_len = x25->neighbour->extended ? X25_EXT_MIN_LEN :
  55                                                     X25_STD_MIN_LEN;
  56         int max_len = x25_pacsize_to_bytes(x25->facilities.pacsize_out);
  57 
  58         if (skb->len - header_len > max_len) {
  59                 
  60                 skb_copy_from_linear_data(skb, header, header_len);
  61                 skb_pull(skb, header_len);
  62 
  63                 frontlen = skb_headroom(skb);
  64 
  65                 while (skb->len > 0) {
  66                         release_sock(sk);
  67                         skbn = sock_alloc_send_skb(sk, frontlen + max_len,
  68                                                    noblock, &err);
  69                         lock_sock(sk);
  70                         if (!skbn) {
  71                                 if (err == -EWOULDBLOCK && noblock){
  72                                         kfree_skb(skb);
  73                                         return sent;
  74                                 }
  75                                 SOCK_DEBUG(sk, "x25_output: fragment alloc"
  76                                                " failed, err=%d, %d bytes "
  77                                                "sent\n", err, sent);
  78                                 return err;
  79                         }
  80 
  81                         skb_reserve(skbn, frontlen);
  82 
  83                         len = max_len > skb->len ? skb->len : max_len;
  84 
  85                         
  86                         skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
  87                         skb_pull(skb, len);
  88 
  89                         
  90                         skb_push(skbn, header_len);
  91                         skb_copy_to_linear_data(skbn, header, header_len);
  92 
  93                         if (skb->len > 0) {
  94                                 if (x25->neighbour->extended)
  95                                         skbn->data[3] |= X25_EXT_M_BIT;
  96                                 else
  97                                         skbn->data[2] |= X25_STD_M_BIT;
  98                         }
  99 
 100                         skb_queue_tail(&sk->sk_write_queue, skbn);
 101                         sent += len;
 102                 }
 103 
 104                 kfree_skb(skb);
 105         } else {
 106                 skb_queue_tail(&sk->sk_write_queue, skb);
 107                 sent = skb->len - header_len;
 108         }
 109         return sent;
 110 }
 111 
 112 
 113 
 114 
 115 
 116 static void x25_send_iframe(struct sock *sk, struct sk_buff *skb)
 117 {
 118         struct x25_sock *x25 = x25_sk(sk);
 119 
 120         if (!skb)
 121                 return;
 122 
 123         if (x25->neighbour->extended) {
 124                 skb->data[2]  = (x25->vs << 1) & 0xFE;
 125                 skb->data[3] &= X25_EXT_M_BIT;
 126                 skb->data[3] |= (x25->vr << 1) & 0xFE;
 127         } else {
 128                 skb->data[2] &= X25_STD_M_BIT;
 129                 skb->data[2] |= (x25->vs << 1) & 0x0E;
 130                 skb->data[2] |= (x25->vr << 5) & 0xE0;
 131         }
 132 
 133         x25_transmit_link(skb, x25->neighbour);
 134 }
 135 
 136 void x25_kick(struct sock *sk)
 137 {
 138         struct sk_buff *skb, *skbn;
 139         unsigned short start, end;
 140         int modulus;
 141         struct x25_sock *x25 = x25_sk(sk);
 142 
 143         if (x25->state != X25_STATE_3)
 144                 return;
 145 
 146         
 147 
 148 
 149         if (skb_peek(&x25->interrupt_out_queue) != NULL &&
 150                 !test_and_set_bit(X25_INTERRUPT_FLAG, &x25->flags)) {
 151 
 152                 skb = skb_dequeue(&x25->interrupt_out_queue);
 153                 x25_transmit_link(skb, x25->neighbour);
 154         }
 155 
 156         if (x25->condition & X25_COND_PEER_RX_BUSY)
 157                 return;
 158 
 159         if (!skb_peek(&sk->sk_write_queue))
 160                 return;
 161 
 162         modulus = x25->neighbour->extended ? X25_EMODULUS : X25_SMODULUS;
 163 
 164         start   = skb_peek(&x25->ack_queue) ? x25->vs : x25->va;
 165         end     = (x25->va + x25->facilities.winsize_out) % modulus;
 166 
 167         if (start == end)
 168                 return;
 169 
 170         x25->vs = start;
 171 
 172         
 173 
 174 
 175 
 176 
 177         skb = skb_dequeue(&sk->sk_write_queue);
 178 
 179         do {
 180                 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
 181                         skb_queue_head(&sk->sk_write_queue, skb);
 182                         break;
 183                 }
 184 
 185                 skb_set_owner_w(skbn, sk);
 186 
 187                 
 188 
 189 
 190                 x25_send_iframe(sk, skbn);
 191 
 192                 x25->vs = (x25->vs + 1) % modulus;
 193 
 194                 
 195 
 196 
 197                 skb_queue_tail(&x25->ack_queue, skb);
 198 
 199         } while (x25->vs != end &&
 200                  (skb = skb_dequeue(&sk->sk_write_queue)) != NULL);
 201 
 202         x25->vl         = x25->vr;
 203         x25->condition &= ~X25_COND_ACK_PENDING;
 204 
 205         x25_stop_timer(sk);
 206 }
 207 
 208 
 209 
 210 
 211 
 212 
 213 void x25_enquiry_response(struct sock *sk)
 214 {
 215         struct x25_sock *x25 = x25_sk(sk);
 216 
 217         if (x25->condition & X25_COND_OWN_RX_BUSY)
 218                 x25_write_internal(sk, X25_RNR);
 219         else
 220                 x25_write_internal(sk, X25_RR);
 221 
 222         x25->vl         = x25->vr;
 223         x25->condition &= ~X25_COND_ACK_PENDING;
 224 
 225         x25_stop_timer(sk);
 226 }