Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  X.25 Packet Layer release 002
0004  *
0005  *  This is ALPHA test software. This code may break your machine,
0006  *  randomly fail to work with new releases, misbehave and/or generally
0007  *  screw up. It might even work.
0008  *
0009  *  This code REQUIRES 2.1.15 or higher
0010  *
0011  *  History
0012  *  X.25 001    Jonathan Naylor Started coding.
0013  *  X.25 002    Jonathan Naylor New timer architecture.
0014  *  2000-09-04  Henner Eisen    Prevented x25_output() skb leakage.
0015  *  2000-10-27  Henner Eisen    MSG_DONTWAIT for fragment allocation.
0016  *  2000-11-10  Henner Eisen    x25_send_iframe(): re-queued frames
0017  *                  needed cleaned seq-number fields.
0018  */
0019 
0020 #include <linux/slab.h>
0021 #include <linux/socket.h>
0022 #include <linux/kernel.h>
0023 #include <linux/string.h>
0024 #include <linux/skbuff.h>
0025 #include <net/sock.h>
0026 #include <net/x25.h>
0027 
0028 static int x25_pacsize_to_bytes(unsigned int pacsize)
0029 {
0030     int bytes = 1;
0031 
0032     if (!pacsize)
0033         return 128;
0034 
0035     while (pacsize-- > 0)
0036         bytes *= 2;
0037 
0038     return bytes;
0039 }
0040 
0041 /*
0042  *  This is where all X.25 information frames pass.
0043  *
0044  *      Returns the amount of user data bytes sent on success
0045  *      or a negative error code on failure.
0046  */
0047 int x25_output(struct sock *sk, struct sk_buff *skb)
0048 {
0049     struct sk_buff *skbn;
0050     unsigned char header[X25_EXT_MIN_LEN];
0051     int err, frontlen, len;
0052     int sent=0, noblock = X25_SKB_CB(skb)->flags & MSG_DONTWAIT;
0053     struct x25_sock *x25 = x25_sk(sk);
0054     int header_len = x25->neighbour->extended ? X25_EXT_MIN_LEN :
0055                             X25_STD_MIN_LEN;
0056     int max_len = x25_pacsize_to_bytes(x25->facilities.pacsize_out);
0057 
0058     if (skb->len - header_len > max_len) {
0059         /* Save a copy of the Header */
0060         skb_copy_from_linear_data(skb, header, header_len);
0061         skb_pull(skb, header_len);
0062 
0063         frontlen = skb_headroom(skb);
0064 
0065         while (skb->len > 0) {
0066             release_sock(sk);
0067             skbn = sock_alloc_send_skb(sk, frontlen + max_len,
0068                            noblock, &err);
0069             lock_sock(sk);
0070             if (!skbn) {
0071                 if (err == -EWOULDBLOCK && noblock){
0072                     kfree_skb(skb);
0073                     return sent;
0074                 }
0075                 SOCK_DEBUG(sk, "x25_output: fragment alloc"
0076                            " failed, err=%d, %d bytes "
0077                            "sent\n", err, sent);
0078                 return err;
0079             }
0080 
0081             skb_reserve(skbn, frontlen);
0082 
0083             len = max_len > skb->len ? skb->len : max_len;
0084 
0085             /* Copy the user data */
0086             skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
0087             skb_pull(skb, len);
0088 
0089             /* Duplicate the Header */
0090             skb_push(skbn, header_len);
0091             skb_copy_to_linear_data(skbn, header, header_len);
0092 
0093             if (skb->len > 0) {
0094                 if (x25->neighbour->extended)
0095                     skbn->data[3] |= X25_EXT_M_BIT;
0096                 else
0097                     skbn->data[2] |= X25_STD_M_BIT;
0098             }
0099 
0100             skb_queue_tail(&sk->sk_write_queue, skbn);
0101             sent += len;
0102         }
0103 
0104         kfree_skb(skb);
0105     } else {
0106         skb_queue_tail(&sk->sk_write_queue, skb);
0107         sent = skb->len - header_len;
0108     }
0109     return sent;
0110 }
0111 
0112 /*
0113  *  This procedure is passed a buffer descriptor for an iframe. It builds
0114  *  the rest of the control part of the frame and then writes it out.
0115  */
0116 static void x25_send_iframe(struct sock *sk, struct sk_buff *skb)
0117 {
0118     struct x25_sock *x25 = x25_sk(sk);
0119 
0120     if (!skb)
0121         return;
0122 
0123     if (x25->neighbour->extended) {
0124         skb->data[2]  = (x25->vs << 1) & 0xFE;
0125         skb->data[3] &= X25_EXT_M_BIT;
0126         skb->data[3] |= (x25->vr << 1) & 0xFE;
0127     } else {
0128         skb->data[2] &= X25_STD_M_BIT;
0129         skb->data[2] |= (x25->vs << 1) & 0x0E;
0130         skb->data[2] |= (x25->vr << 5) & 0xE0;
0131     }
0132 
0133     x25_transmit_link(skb, x25->neighbour);
0134 }
0135 
0136 void x25_kick(struct sock *sk)
0137 {
0138     struct sk_buff *skb, *skbn;
0139     unsigned short start, end;
0140     int modulus;
0141     struct x25_sock *x25 = x25_sk(sk);
0142 
0143     if (x25->state != X25_STATE_3)
0144         return;
0145 
0146     /*
0147      *  Transmit interrupt data.
0148      */
0149     if (skb_peek(&x25->interrupt_out_queue) != NULL &&
0150         !test_and_set_bit(X25_INTERRUPT_FLAG, &x25->flags)) {
0151 
0152         skb = skb_dequeue(&x25->interrupt_out_queue);
0153         x25_transmit_link(skb, x25->neighbour);
0154     }
0155 
0156     if (x25->condition & X25_COND_PEER_RX_BUSY)
0157         return;
0158 
0159     if (!skb_peek(&sk->sk_write_queue))
0160         return;
0161 
0162     modulus = x25->neighbour->extended ? X25_EMODULUS : X25_SMODULUS;
0163 
0164     start   = skb_peek(&x25->ack_queue) ? x25->vs : x25->va;
0165     end     = (x25->va + x25->facilities.winsize_out) % modulus;
0166 
0167     if (start == end)
0168         return;
0169 
0170     x25->vs = start;
0171 
0172     /*
0173      * Transmit data until either we're out of data to send or
0174      * the window is full.
0175      */
0176 
0177     skb = skb_dequeue(&sk->sk_write_queue);
0178 
0179     do {
0180         if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
0181             skb_queue_head(&sk->sk_write_queue, skb);
0182             break;
0183         }
0184 
0185         skb_set_owner_w(skbn, sk);
0186 
0187         /*
0188          * Transmit the frame copy.
0189          */
0190         x25_send_iframe(sk, skbn);
0191 
0192         x25->vs = (x25->vs + 1) % modulus;
0193 
0194         /*
0195          * Requeue the original data frame.
0196          */
0197         skb_queue_tail(&x25->ack_queue, skb);
0198 
0199     } while (x25->vs != end &&
0200          (skb = skb_dequeue(&sk->sk_write_queue)) != NULL);
0201 
0202     x25->vl         = x25->vr;
0203     x25->condition &= ~X25_COND_ACK_PENDING;
0204 
0205     x25_stop_timer(sk);
0206 }
0207 
0208 /*
0209  * The following routines are taken from page 170 of the 7th ARRL Computer
0210  * Networking Conference paper, as is the whole state machine.
0211  */
0212 
0213 void x25_enquiry_response(struct sock *sk)
0214 {
0215     struct x25_sock *x25 = x25_sk(sk);
0216 
0217     if (x25->condition & X25_COND_OWN_RX_BUSY)
0218         x25_write_internal(sk, X25_RNR);
0219     else
0220         x25_write_internal(sk, X25_RR);
0221 
0222     x25->vl         = x25->vr;
0223     x25->condition &= ~X25_COND_ACK_PENDING;
0224 
0225     x25_stop_timer(sk);
0226 }