1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) 8 */ 9 #include <linux/errno.h> 10 #include <linux/types.h> 11 #include <linux/socket.h> 12 #include <linux/in.h> 13 #include <linux/kernel.h> 14 #include <linux/timer.h> 15 #include <linux/string.h> 16 #include <linux/sockios.h> 17 #include <linux/net.h> 18 #include <linux/slab.h> 19 #include <net/ax25.h> 20 #include <linux/inet.h> 21 #include <linux/netdevice.h> 22 #include <linux/skbuff.h> 23 #include <net/sock.h> 24 #include <net/tcp_states.h> 25 #include <asm/uaccess.h> 26 #include <asm/system.h> 27 #include <linux/fcntl.h> 28 #include <linux/mm.h> 29 #include <linux/interrupt.h> 30 #include <net/netrom.h> 31 32 /* 33 * This routine purges all of the queues of frames. 34 */ 35 void nr_clear_queues(struct sock *sk) 36 { 37 struct nr_sock *nr = nr_sk(sk); 38 39 skb_queue_purge(&sk->sk_write_queue); 40 skb_queue_purge(&nr->ack_queue); 41 skb_queue_purge(&nr->reseq_queue); 42 skb_queue_purge(&nr->frag_queue); 43 } 44 45 /* 46 * This routine purges the input queue of those frames that have been 47 * acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the 48 * SDL diagram. 49 */ 50 void nr_frames_acked(struct sock *sk, unsigned short nr) 51 { 52 struct nr_sock *nrom = nr_sk(sk); 53 struct sk_buff *skb; 54 55 /* 56 * Remove all the ack-ed frames from the ack queue. 57 */ 58 if (nrom->va != nr) { 59 while (skb_peek(&nrom->ack_queue) != NULL && nrom->va != nr) { 60 skb = skb_dequeue(&nrom->ack_queue); 61 kfree_skb(skb); 62 nrom->va = (nrom->va + 1) % NR_MODULUS; 63 } 64 } 65 } 66 67 /* 68 * Requeue all the un-ack-ed frames on the output queue to be picked 69 * up by nr_kick called from the timer. This arrangement handles the 70 * possibility of an empty output queue. 71 */ 72 void nr_requeue_frames(struct sock *sk) 73 { 74 struct sk_buff *skb, *skb_prev = NULL; 75 76 while ((skb = skb_dequeue(&nr_sk(sk)->ack_queue)) != NULL) { 77 if (skb_prev == NULL) 78 skb_queue_head(&sk->sk_write_queue, skb); 79 else 80 skb_append(skb_prev, skb, &sk->sk_write_queue); 81 skb_prev = skb; 82 } 83 } 84 85 /* 86 * Validate that the value of nr is between va and vs. Return true or 87 * false for testing. 88 */ 89 int nr_validate_nr(struct sock *sk, unsigned short nr) 90 { 91 struct nr_sock *nrom = nr_sk(sk); 92 unsigned short vc = nrom->va; 93 94 while (vc != nrom->vs) { 95 if (nr == vc) return 1; 96 vc = (vc + 1) % NR_MODULUS; 97 } 98 99 return nr == nrom->vs; 100 } 101 102 /* 103 * Check that ns is within the receive window. 104 */ 105 int nr_in_rx_window(struct sock *sk, unsigned short ns) 106 { 107 struct nr_sock *nr = nr_sk(sk); 108 unsigned short vc = nr->vr; 109 unsigned short vt = (nr->vl + nr->window) % NR_MODULUS; 110 111 while (vc != vt) { 112 if (ns == vc) return 1; 113 vc = (vc + 1) % NR_MODULUS; 114 } 115 116 return 0; 117 } 118 119 /* 120 * This routine is called when the HDLC layer internally generates a 121 * control frame. 122 */ 123 void nr_write_internal(struct sock *sk, int frametype) 124 { 125 struct nr_sock *nr = nr_sk(sk); 126 struct sk_buff *skb; 127 unsigned char *dptr; 128 int len, timeout; 129 130 len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; 131 132 switch (frametype & 0x0F) { 133 case NR_CONNREQ: 134 len += 17; 135 break; 136 case NR_CONNACK: 137 len += (nr->bpqext) ? 2 : 1; 138 break; 139 case NR_DISCREQ: 140 case NR_DISCACK: 141 case NR_INFOACK: 142 break; 143 default: 144 printk(KERN_ERR "NET/ROM: nr_write_internal - invalid frame type %d\n", frametype); 145 return; 146 } 147 148 if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL) 149 return; 150 151 /* 152 * Space for AX.25 and NET/ROM network header 153 */ 154 skb_reserve(skb, NR_NETWORK_LEN); 155 156 dptr = skb_put(skb, skb_tailroom(skb)); 157 158 switch (frametype & 0x0F) { 159 case NR_CONNREQ: 160 timeout = nr->t1 / HZ; 161 *dptr++ = nr->my_index; 162 *dptr++ = nr->my_id; 163 *dptr++ = 0; 164 *dptr++ = 0; 165 *dptr++ = frametype; 166 *dptr++ = nr->window; 167 memcpy(dptr, &nr->user_addr, AX25_ADDR_LEN); 168 dptr[6] &= ~AX25_CBIT; 169 dptr[6] &= ~AX25_EBIT; 170 dptr[6] |= AX25_SSSID_SPARE; 171 dptr += AX25_ADDR_LEN; 172 memcpy(dptr, &nr->source_addr, AX25_ADDR_LEN); 173 dptr[6] &= ~AX25_CBIT; 174 dptr[6] &= ~AX25_EBIT; 175 dptr[6] |= AX25_SSSID_SPARE; 176 dptr += AX25_ADDR_LEN; 177 *dptr++ = timeout % 256; 178 *dptr++ = timeout / 256; 179 break; 180 181 case NR_CONNACK: 182 *dptr++ = nr->your_index; 183 *dptr++ = nr->your_id; 184 *dptr++ = nr->my_index; 185 *dptr++ = nr->my_id; 186 *dptr++ = frametype; 187 *dptr++ = nr->window; 188 if (nr->bpqext) *dptr++ = sysctl_netrom_network_ttl_initialiser; 189 break; 190 191 case NR_DISCREQ: 192 case NR_DISCACK: 193 *dptr++ = nr->your_index; 194 *dptr++ = nr->your_id; 195 *dptr++ = 0; 196 *dptr++ = 0; 197 *dptr++ = frametype; 198 break; 199 200 case NR_INFOACK: 201 *dptr++ = nr->your_index; 202 *dptr++ = nr->your_id; 203 *dptr++ = 0; 204 *dptr++ = nr->vr; 205 *dptr++ = frametype; 206 break; 207 } 208 209 nr_transmit_buffer(sk, skb); 210 } 211 212 /* 213 * This routine is called to send an error reply. 214 */ 215 void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags) 216 { 217 struct sk_buff *skbn; 218 unsigned char *dptr; 219 int len; 220 221 len = NR_NETWORK_LEN + NR_TRANSPORT_LEN + 1; 222 223 if ((skbn = alloc_skb(len, GFP_ATOMIC)) == NULL) 224 return; 225 226 skb_reserve(skbn, 0); 227 228 dptr = skb_put(skbn, NR_NETWORK_LEN + NR_TRANSPORT_LEN); 229 230 skb_copy_from_linear_data_offset(skb, 7, dptr, AX25_ADDR_LEN); 231 dptr[6] &= ~AX25_CBIT; 232 dptr[6] &= ~AX25_EBIT; 233 dptr[6] |= AX25_SSSID_SPARE; 234 dptr += AX25_ADDR_LEN; 235 236 skb_copy_from_linear_data(skb, dptr, AX25_ADDR_LEN); 237 dptr[6] &= ~AX25_CBIT; 238 dptr[6] |= AX25_EBIT; 239 dptr[6] |= AX25_SSSID_SPARE; 240 dptr += AX25_ADDR_LEN; 241 242 *dptr++ = sysctl_netrom_network_ttl_initialiser; 243 244 if (mine) { 245 *dptr++ = 0; 246 *dptr++ = 0; 247 *dptr++ = skb->data[15]; 248 *dptr++ = skb->data[16]; 249 } else { 250 *dptr++ = skb->data[15]; 251 *dptr++ = skb->data[16]; 252 *dptr++ = 0; 253 *dptr++ = 0; 254 } 255 256 *dptr++ = cmdflags; 257 *dptr++ = 0; 258 259 if (!nr_route_frame(skbn, NULL)) 260 kfree_skb(skbn); 261 } 262 263 void nr_disconnect(struct sock *sk, int reason) 264 { 265 nr_stop_t1timer(sk); 266 nr_stop_t2timer(sk); 267 nr_stop_t4timer(sk); 268 nr_stop_idletimer(sk); 269 270 nr_clear_queues(sk); 271 272 nr_sk(sk)->state = NR_STATE_0; 273 274 sk->sk_state = TCP_CLOSE; 275 sk->sk_err = reason; 276 sk->sk_shutdown |= SEND_SHUTDOWN; 277 278 if (!sock_flag(sk, SOCK_DEAD)) { 279 sk->sk_state_change(sk); 280 sock_set_flag(sk, SOCK_DEAD); 281 } 282 } 283