0001
0002
0003
0004
0005
0006 #include <linux/errno.h>
0007 #include <linux/types.h>
0008 #include <linux/socket.h>
0009 #include <linux/in.h>
0010 #include <linux/kernel.h>
0011 #include <linux/timer.h>
0012 #include <linux/string.h>
0013 #include <linux/sockios.h>
0014 #include <linux/net.h>
0015 #include <linux/slab.h>
0016 #include <net/ax25.h>
0017 #include <linux/inet.h>
0018 #include <linux/netdevice.h>
0019 #include <linux/skbuff.h>
0020 #include <net/sock.h>
0021 #include <net/tcp_states.h>
0022 #include <linux/uaccess.h>
0023 #include <linux/fcntl.h>
0024 #include <linux/mm.h>
0025 #include <linux/interrupt.h>
0026 #include <net/netrom.h>
0027
0028
0029
0030
0031 void nr_clear_queues(struct sock *sk)
0032 {
0033 struct nr_sock *nr = nr_sk(sk);
0034
0035 skb_queue_purge(&sk->sk_write_queue);
0036 skb_queue_purge(&nr->ack_queue);
0037 skb_queue_purge(&nr->reseq_queue);
0038 skb_queue_purge(&nr->frag_queue);
0039 }
0040
0041
0042
0043
0044
0045
0046 void nr_frames_acked(struct sock *sk, unsigned short nr)
0047 {
0048 struct nr_sock *nrom = nr_sk(sk);
0049 struct sk_buff *skb;
0050
0051
0052
0053
0054 if (nrom->va != nr) {
0055 while (skb_peek(&nrom->ack_queue) != NULL && nrom->va != nr) {
0056 skb = skb_dequeue(&nrom->ack_queue);
0057 kfree_skb(skb);
0058 nrom->va = (nrom->va + 1) % NR_MODULUS;
0059 }
0060 }
0061 }
0062
0063
0064
0065
0066
0067
0068 void nr_requeue_frames(struct sock *sk)
0069 {
0070 struct sk_buff *skb, *skb_prev = NULL;
0071
0072 while ((skb = skb_dequeue(&nr_sk(sk)->ack_queue)) != NULL) {
0073 if (skb_prev == NULL)
0074 skb_queue_head(&sk->sk_write_queue, skb);
0075 else
0076 skb_append(skb_prev, skb, &sk->sk_write_queue);
0077 skb_prev = skb;
0078 }
0079 }
0080
0081
0082
0083
0084
0085 int nr_validate_nr(struct sock *sk, unsigned short nr)
0086 {
0087 struct nr_sock *nrom = nr_sk(sk);
0088 unsigned short vc = nrom->va;
0089
0090 while (vc != nrom->vs) {
0091 if (nr == vc) return 1;
0092 vc = (vc + 1) % NR_MODULUS;
0093 }
0094
0095 return nr == nrom->vs;
0096 }
0097
0098
0099
0100
0101 int nr_in_rx_window(struct sock *sk, unsigned short ns)
0102 {
0103 struct nr_sock *nr = nr_sk(sk);
0104 unsigned short vc = nr->vr;
0105 unsigned short vt = (nr->vl + nr->window) % NR_MODULUS;
0106
0107 while (vc != vt) {
0108 if (ns == vc) return 1;
0109 vc = (vc + 1) % NR_MODULUS;
0110 }
0111
0112 return 0;
0113 }
0114
0115
0116
0117
0118
0119 void nr_write_internal(struct sock *sk, int frametype)
0120 {
0121 struct nr_sock *nr = nr_sk(sk);
0122 struct sk_buff *skb;
0123 unsigned char *dptr;
0124 int len, timeout;
0125
0126 len = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
0127
0128 switch (frametype & 0x0F) {
0129 case NR_CONNREQ:
0130 len += 17;
0131 break;
0132 case NR_CONNACK:
0133 len += (nr->bpqext) ? 2 : 1;
0134 break;
0135 case NR_DISCREQ:
0136 case NR_DISCACK:
0137 case NR_INFOACK:
0138 break;
0139 default:
0140 printk(KERN_ERR "NET/ROM: nr_write_internal - invalid frame type %d\n", frametype);
0141 return;
0142 }
0143
0144 if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
0145 return;
0146
0147
0148
0149
0150 skb_reserve(skb, NR_NETWORK_LEN);
0151
0152 dptr = skb_put(skb, skb_tailroom(skb));
0153
0154 switch (frametype & 0x0F) {
0155 case NR_CONNREQ:
0156 timeout = nr->t1 / HZ;
0157 *dptr++ = nr->my_index;
0158 *dptr++ = nr->my_id;
0159 *dptr++ = 0;
0160 *dptr++ = 0;
0161 *dptr++ = frametype;
0162 *dptr++ = nr->window;
0163 memcpy(dptr, &nr->user_addr, AX25_ADDR_LEN);
0164 dptr[6] &= ~AX25_CBIT;
0165 dptr[6] &= ~AX25_EBIT;
0166 dptr[6] |= AX25_SSSID_SPARE;
0167 dptr += AX25_ADDR_LEN;
0168 memcpy(dptr, &nr->source_addr, AX25_ADDR_LEN);
0169 dptr[6] &= ~AX25_CBIT;
0170 dptr[6] &= ~AX25_EBIT;
0171 dptr[6] |= AX25_SSSID_SPARE;
0172 dptr += AX25_ADDR_LEN;
0173 *dptr++ = timeout % 256;
0174 *dptr++ = timeout / 256;
0175 break;
0176
0177 case NR_CONNACK:
0178 *dptr++ = nr->your_index;
0179 *dptr++ = nr->your_id;
0180 *dptr++ = nr->my_index;
0181 *dptr++ = nr->my_id;
0182 *dptr++ = frametype;
0183 *dptr++ = nr->window;
0184 if (nr->bpqext) *dptr++ = sysctl_netrom_network_ttl_initialiser;
0185 break;
0186
0187 case NR_DISCREQ:
0188 case NR_DISCACK:
0189 *dptr++ = nr->your_index;
0190 *dptr++ = nr->your_id;
0191 *dptr++ = 0;
0192 *dptr++ = 0;
0193 *dptr++ = frametype;
0194 break;
0195
0196 case NR_INFOACK:
0197 *dptr++ = nr->your_index;
0198 *dptr++ = nr->your_id;
0199 *dptr++ = 0;
0200 *dptr++ = nr->vr;
0201 *dptr++ = frametype;
0202 break;
0203 }
0204
0205 nr_transmit_buffer(sk, skb);
0206 }
0207
0208
0209
0210
0211 void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags)
0212 {
0213 struct sk_buff *skbn;
0214 unsigned char *dptr;
0215 int len;
0216
0217 len = NR_NETWORK_LEN + NR_TRANSPORT_LEN + 1;
0218
0219 if ((skbn = alloc_skb(len, GFP_ATOMIC)) == NULL)
0220 return;
0221
0222 skb_reserve(skbn, 0);
0223
0224 dptr = skb_put(skbn, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
0225
0226 skb_copy_from_linear_data_offset(skb, 7, dptr, AX25_ADDR_LEN);
0227 dptr[6] &= ~AX25_CBIT;
0228 dptr[6] &= ~AX25_EBIT;
0229 dptr[6] |= AX25_SSSID_SPARE;
0230 dptr += AX25_ADDR_LEN;
0231
0232 skb_copy_from_linear_data(skb, dptr, AX25_ADDR_LEN);
0233 dptr[6] &= ~AX25_CBIT;
0234 dptr[6] |= AX25_EBIT;
0235 dptr[6] |= AX25_SSSID_SPARE;
0236 dptr += AX25_ADDR_LEN;
0237
0238 *dptr++ = sysctl_netrom_network_ttl_initialiser;
0239
0240 if (mine) {
0241 *dptr++ = 0;
0242 *dptr++ = 0;
0243 *dptr++ = skb->data[15];
0244 *dptr++ = skb->data[16];
0245 } else {
0246 *dptr++ = skb->data[15];
0247 *dptr++ = skb->data[16];
0248 *dptr++ = 0;
0249 *dptr++ = 0;
0250 }
0251
0252 *dptr++ = cmdflags;
0253 *dptr++ = 0;
0254
0255 if (!nr_route_frame(skbn, NULL))
0256 kfree_skb(skbn);
0257 }
0258
0259 void nr_disconnect(struct sock *sk, int reason)
0260 {
0261 nr_stop_t1timer(sk);
0262 nr_stop_t2timer(sk);
0263 nr_stop_t4timer(sk);
0264 nr_stop_idletimer(sk);
0265
0266 nr_clear_queues(sk);
0267
0268 nr_sk(sk)->state = NR_STATE_0;
0269
0270 sk->sk_state = TCP_CLOSE;
0271 sk->sk_err = reason;
0272 sk->sk_shutdown |= SEND_SHUTDOWN;
0273
0274 if (!sock_flag(sk, SOCK_DEAD)) {
0275 sk->sk_state_change(sk);
0276 sock_set_flag(sk, SOCK_DEAD);
0277 }
0278 }