Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *
0004  * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
0005  * Copyright Darryl Miles G7LED (dlm@g7led.demon.co.uk)
0006  */
0007 #include <linux/errno.h>
0008 #include <linux/types.h>
0009 #include <linux/socket.h>
0010 #include <linux/in.h>
0011 #include <linux/kernel.h>
0012 #include <linux/timer.h>
0013 #include <linux/string.h>
0014 #include <linux/sockios.h>
0015 #include <linux/net.h>
0016 #include <linux/slab.h>
0017 #include <net/ax25.h>
0018 #include <linux/inet.h>
0019 #include <linux/netdevice.h>
0020 #include <linux/skbuff.h>
0021 #include <net/sock.h>
0022 #include <net/tcp_states.h>
0023 #include <linux/uaccess.h>
0024 #include <linux/fcntl.h>
0025 #include <linux/mm.h>
0026 #include <linux/interrupt.h>
0027 #include <net/netrom.h>
0028 
0029 static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
0030 {
0031     struct sk_buff *skbo, *skbn = skb;
0032     struct nr_sock *nr = nr_sk(sk);
0033 
0034     skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
0035 
0036     nr_start_idletimer(sk);
0037 
0038     if (more) {
0039         nr->fraglen += skb->len;
0040         skb_queue_tail(&nr->frag_queue, skb);
0041         return 0;
0042     }
0043 
0044     if (!more && nr->fraglen > 0) { /* End of fragment */
0045         nr->fraglen += skb->len;
0046         skb_queue_tail(&nr->frag_queue, skb);
0047 
0048         if ((skbn = alloc_skb(nr->fraglen, GFP_ATOMIC)) == NULL)
0049             return 1;
0050 
0051         skb_reset_transport_header(skbn);
0052 
0053         while ((skbo = skb_dequeue(&nr->frag_queue)) != NULL) {
0054             skb_copy_from_linear_data(skbo,
0055                           skb_put(skbn, skbo->len),
0056                           skbo->len);
0057             kfree_skb(skbo);
0058         }
0059 
0060         nr->fraglen = 0;
0061     }
0062 
0063     return sock_queue_rcv_skb(sk, skbn);
0064 }
0065 
0066 /*
0067  * State machine for state 1, Awaiting Connection State.
0068  * The handling of the timer(s) is in file nr_timer.c.
0069  * Handling of state 0 and connection release is in netrom.c.
0070  */
0071 static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
0072     int frametype)
0073 {
0074     switch (frametype) {
0075     case NR_CONNACK: {
0076         struct nr_sock *nr = nr_sk(sk);
0077 
0078         nr_stop_t1timer(sk);
0079         nr_start_idletimer(sk);
0080         nr->your_index = skb->data[17];
0081         nr->your_id    = skb->data[18];
0082         nr->vs         = 0;
0083         nr->va         = 0;
0084         nr->vr         = 0;
0085         nr->vl         = 0;
0086         nr->state      = NR_STATE_3;
0087         nr->n2count    = 0;
0088         nr->window     = skb->data[20];
0089         sk->sk_state   = TCP_ESTABLISHED;
0090         if (!sock_flag(sk, SOCK_DEAD))
0091             sk->sk_state_change(sk);
0092         break;
0093     }
0094 
0095     case NR_CONNACK | NR_CHOKE_FLAG:
0096         nr_disconnect(sk, ECONNREFUSED);
0097         break;
0098 
0099     case NR_RESET:
0100         if (sysctl_netrom_reset_circuit)
0101             nr_disconnect(sk, ECONNRESET);
0102         break;
0103 
0104     default:
0105         break;
0106     }
0107     return 0;
0108 }
0109 
0110 /*
0111  * State machine for state 2, Awaiting Release State.
0112  * The handling of the timer(s) is in file nr_timer.c
0113  * Handling of state 0 and connection release is in netrom.c.
0114  */
0115 static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
0116     int frametype)
0117 {
0118     switch (frametype) {
0119     case NR_CONNACK | NR_CHOKE_FLAG:
0120         nr_disconnect(sk, ECONNRESET);
0121         break;
0122 
0123     case NR_DISCREQ:
0124         nr_write_internal(sk, NR_DISCACK);
0125         fallthrough;
0126     case NR_DISCACK:
0127         nr_disconnect(sk, 0);
0128         break;
0129 
0130     case NR_RESET:
0131         if (sysctl_netrom_reset_circuit)
0132             nr_disconnect(sk, ECONNRESET);
0133         break;
0134 
0135     default:
0136         break;
0137     }
0138     return 0;
0139 }
0140 
0141 /*
0142  * State machine for state 3, Connected State.
0143  * The handling of the timer(s) is in file nr_timer.c
0144  * Handling of state 0 and connection release is in netrom.c.
0145  */
0146 static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype)
0147 {
0148     struct nr_sock *nrom = nr_sk(sk);
0149     struct sk_buff_head temp_queue;
0150     struct sk_buff *skbn;
0151     unsigned short save_vr;
0152     unsigned short nr, ns;
0153     int queued = 0;
0154 
0155     nr = skb->data[18];
0156 
0157     switch (frametype) {
0158     case NR_CONNREQ:
0159         nr_write_internal(sk, NR_CONNACK);
0160         break;
0161 
0162     case NR_DISCREQ:
0163         nr_write_internal(sk, NR_DISCACK);
0164         nr_disconnect(sk, 0);
0165         break;
0166 
0167     case NR_CONNACK | NR_CHOKE_FLAG:
0168     case NR_DISCACK:
0169         nr_disconnect(sk, ECONNRESET);
0170         break;
0171 
0172     case NR_INFOACK:
0173     case NR_INFOACK | NR_CHOKE_FLAG:
0174     case NR_INFOACK | NR_NAK_FLAG:
0175     case NR_INFOACK | NR_NAK_FLAG | NR_CHOKE_FLAG:
0176         if (frametype & NR_CHOKE_FLAG) {
0177             nrom->condition |= NR_COND_PEER_RX_BUSY;
0178             nr_start_t4timer(sk);
0179         } else {
0180             nrom->condition &= ~NR_COND_PEER_RX_BUSY;
0181             nr_stop_t4timer(sk);
0182         }
0183         if (!nr_validate_nr(sk, nr)) {
0184             break;
0185         }
0186         if (frametype & NR_NAK_FLAG) {
0187             nr_frames_acked(sk, nr);
0188             nr_send_nak_frame(sk);
0189         } else {
0190             if (nrom->condition & NR_COND_PEER_RX_BUSY) {
0191                 nr_frames_acked(sk, nr);
0192             } else {
0193                 nr_check_iframes_acked(sk, nr);
0194             }
0195         }
0196         break;
0197 
0198     case NR_INFO:
0199     case NR_INFO | NR_NAK_FLAG:
0200     case NR_INFO | NR_CHOKE_FLAG:
0201     case NR_INFO | NR_MORE_FLAG:
0202     case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG:
0203     case NR_INFO | NR_CHOKE_FLAG | NR_MORE_FLAG:
0204     case NR_INFO | NR_NAK_FLAG | NR_MORE_FLAG:
0205     case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG | NR_MORE_FLAG:
0206         if (frametype & NR_CHOKE_FLAG) {
0207             nrom->condition |= NR_COND_PEER_RX_BUSY;
0208             nr_start_t4timer(sk);
0209         } else {
0210             nrom->condition &= ~NR_COND_PEER_RX_BUSY;
0211             nr_stop_t4timer(sk);
0212         }
0213         if (nr_validate_nr(sk, nr)) {
0214             if (frametype & NR_NAK_FLAG) {
0215                 nr_frames_acked(sk, nr);
0216                 nr_send_nak_frame(sk);
0217             } else {
0218                 if (nrom->condition & NR_COND_PEER_RX_BUSY) {
0219                     nr_frames_acked(sk, nr);
0220                 } else {
0221                     nr_check_iframes_acked(sk, nr);
0222                 }
0223             }
0224         }
0225         queued = 1;
0226         skb_queue_head(&nrom->reseq_queue, skb);
0227         if (nrom->condition & NR_COND_OWN_RX_BUSY)
0228             break;
0229         skb_queue_head_init(&temp_queue);
0230         do {
0231             save_vr = nrom->vr;
0232             while ((skbn = skb_dequeue(&nrom->reseq_queue)) != NULL) {
0233                 ns = skbn->data[17];
0234                 if (ns == nrom->vr) {
0235                     if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
0236                         nrom->vr = (nrom->vr + 1) % NR_MODULUS;
0237                     } else {
0238                         nrom->condition |= NR_COND_OWN_RX_BUSY;
0239                         skb_queue_tail(&temp_queue, skbn);
0240                     }
0241                 } else if (nr_in_rx_window(sk, ns)) {
0242                     skb_queue_tail(&temp_queue, skbn);
0243                 } else {
0244                     kfree_skb(skbn);
0245                 }
0246             }
0247             while ((skbn = skb_dequeue(&temp_queue)) != NULL) {
0248                 skb_queue_tail(&nrom->reseq_queue, skbn);
0249             }
0250         } while (save_vr != nrom->vr);
0251         /*
0252          * Window is full, ack it immediately.
0253          */
0254         if (((nrom->vl + nrom->window) % NR_MODULUS) == nrom->vr) {
0255             nr_enquiry_response(sk);
0256         } else {
0257             if (!(nrom->condition & NR_COND_ACK_PENDING)) {
0258                 nrom->condition |= NR_COND_ACK_PENDING;
0259                 nr_start_t2timer(sk);
0260             }
0261         }
0262         break;
0263 
0264     case NR_RESET:
0265         if (sysctl_netrom_reset_circuit)
0266             nr_disconnect(sk, ECONNRESET);
0267         break;
0268 
0269     default:
0270         break;
0271     }
0272     return queued;
0273 }
0274 
0275 /* Higher level upcall for a LAPB frame - called with sk locked */
0276 int nr_process_rx_frame(struct sock *sk, struct sk_buff *skb)
0277 {
0278     struct nr_sock *nr = nr_sk(sk);
0279     int queued = 0, frametype;
0280 
0281     if (nr->state == NR_STATE_0)
0282         return 0;
0283 
0284     frametype = skb->data[19];
0285 
0286     switch (nr->state) {
0287     case NR_STATE_1:
0288         queued = nr_state1_machine(sk, skb, frametype);
0289         break;
0290     case NR_STATE_2:
0291         queued = nr_state2_machine(sk, skb, frametype);
0292         break;
0293     case NR_STATE_3:
0294         queued = nr_state3_machine(sk, skb, frametype);
0295         break;
0296     }
0297 
0298     nr_kick(sk);
0299 
0300     return queued;
0301 }