0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/errno.h>
0009 #include <linux/types.h>
0010 #include <linux/socket.h>
0011 #include <linux/in.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/timer.h>
0015 #include <linux/string.h>
0016 #include <linux/sockios.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/net.h>
0019 #include <linux/slab.h>
0020 #include <net/ax25.h>
0021 #include <linux/inet.h>
0022 #include <linux/netdevice.h>
0023 #include <linux/skbuff.h>
0024 #include <net/sock.h>
0025 #include <linux/uaccess.h>
0026 #include <linux/fcntl.h>
0027 #include <linux/mm.h>
0028 #include <linux/interrupt.h>
0029
0030 static DEFINE_SPINLOCK(ax25_frag_lock);
0031
0032 ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, const ax25_address *src, ax25_address *dest, ax25_digi *digi, struct net_device *dev)
0033 {
0034 ax25_dev *ax25_dev;
0035 ax25_cb *ax25;
0036
0037
0038
0039
0040
0041 if (paclen == 0) {
0042 if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
0043 return NULL;
0044
0045 paclen = ax25_dev->values[AX25_VALUES_PACLEN];
0046 }
0047
0048
0049
0050
0051 if ((ax25 = ax25_find_cb(src, dest, digi, dev)) != NULL) {
0052 ax25_output(ax25, paclen, skb);
0053 return ax25;
0054 }
0055
0056 if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
0057 return NULL;
0058
0059 if ((ax25 = ax25_create_cb()) == NULL)
0060 return NULL;
0061
0062 ax25_fillin_cb(ax25, ax25_dev);
0063
0064 ax25->source_addr = *src;
0065 ax25->dest_addr = *dest;
0066
0067 if (digi != NULL) {
0068 ax25->digipeat = kmemdup(digi, sizeof(*digi), GFP_ATOMIC);
0069 if (ax25->digipeat == NULL) {
0070 ax25_cb_put(ax25);
0071 return NULL;
0072 }
0073 }
0074
0075 switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
0076 case AX25_PROTO_STD_SIMPLEX:
0077 case AX25_PROTO_STD_DUPLEX:
0078 ax25_std_establish_data_link(ax25);
0079 break;
0080
0081 #ifdef CONFIG_AX25_DAMA_SLAVE
0082 case AX25_PROTO_DAMA_SLAVE:
0083 if (ax25_dev->dama.slave)
0084 ax25_ds_establish_data_link(ax25);
0085 else
0086 ax25_std_establish_data_link(ax25);
0087 break;
0088 #endif
0089 }
0090
0091
0092
0093
0094
0095 ax25_cb_hold(ax25);
0096
0097 ax25_cb_add(ax25);
0098
0099 ax25->state = AX25_STATE_1;
0100
0101 ax25_start_heartbeat(ax25);
0102
0103 ax25_output(ax25, paclen, skb);
0104
0105 return ax25;
0106 }
0107
0108 EXPORT_SYMBOL(ax25_send_frame);
0109
0110
0111
0112
0113
0114
0115
0116 void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
0117 {
0118 struct sk_buff *skbn;
0119 unsigned char *p;
0120 int frontlen, len, fragno, ka9qfrag, first = 1;
0121
0122 if (paclen < 16) {
0123 WARN_ON_ONCE(1);
0124 kfree_skb(skb);
0125 return;
0126 }
0127
0128 if ((skb->len - 1) > paclen) {
0129 if (*skb->data == AX25_P_TEXT) {
0130 skb_pull(skb, 1);
0131 ka9qfrag = 0;
0132 } else {
0133 paclen -= 2;
0134 ka9qfrag = 1;
0135 }
0136
0137 fragno = skb->len / paclen;
0138 if (skb->len % paclen == 0) fragno--;
0139
0140 frontlen = skb_headroom(skb);
0141
0142 while (skb->len > 0) {
0143 spin_lock_bh(&ax25_frag_lock);
0144 if ((skbn = alloc_skb(paclen + 2 + frontlen, GFP_ATOMIC)) == NULL) {
0145 spin_unlock_bh(&ax25_frag_lock);
0146 printk(KERN_CRIT "AX.25: ax25_output - out of memory\n");
0147 return;
0148 }
0149
0150 if (skb->sk != NULL)
0151 skb_set_owner_w(skbn, skb->sk);
0152
0153 spin_unlock_bh(&ax25_frag_lock);
0154
0155 len = (paclen > skb->len) ? skb->len : paclen;
0156
0157 if (ka9qfrag == 1) {
0158 skb_reserve(skbn, frontlen + 2);
0159 skb_set_network_header(skbn,
0160 skb_network_offset(skb));
0161 skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
0162 p = skb_push(skbn, 2);
0163
0164 *p++ = AX25_P_SEGMENT;
0165
0166 *p = fragno--;
0167 if (first) {
0168 *p |= AX25_SEG_FIRST;
0169 first = 0;
0170 }
0171 } else {
0172 skb_reserve(skbn, frontlen + 1);
0173 skb_set_network_header(skbn,
0174 skb_network_offset(skb));
0175 skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
0176 p = skb_push(skbn, 1);
0177 *p = AX25_P_TEXT;
0178 }
0179
0180 skb_pull(skb, len);
0181 skb_queue_tail(&ax25->write_queue, skbn);
0182 }
0183
0184 kfree_skb(skb);
0185 } else {
0186 skb_queue_tail(&ax25->write_queue, skb);
0187 }
0188
0189 switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
0190 case AX25_PROTO_STD_SIMPLEX:
0191 case AX25_PROTO_STD_DUPLEX:
0192 ax25_kick(ax25);
0193 break;
0194
0195 #ifdef CONFIG_AX25_DAMA_SLAVE
0196
0197
0198
0199
0200 case AX25_PROTO_DAMA_SLAVE:
0201 if (!ax25->ax25_dev->dama.slave) ax25_kick(ax25);
0202 break;
0203 #endif
0204 }
0205 }
0206
0207
0208
0209
0210
0211 static void ax25_send_iframe(ax25_cb *ax25, struct sk_buff *skb, int poll_bit)
0212 {
0213 unsigned char *frame;
0214
0215 if (skb == NULL)
0216 return;
0217
0218 skb_reset_network_header(skb);
0219
0220 if (ax25->modulus == AX25_MODULUS) {
0221 frame = skb_push(skb, 1);
0222
0223 *frame = AX25_I;
0224 *frame |= (poll_bit) ? AX25_PF : 0;
0225 *frame |= (ax25->vr << 5);
0226 *frame |= (ax25->vs << 1);
0227 } else {
0228 frame = skb_push(skb, 2);
0229
0230 frame[0] = AX25_I;
0231 frame[0] |= (ax25->vs << 1);
0232 frame[1] = (poll_bit) ? AX25_EPF : 0;
0233 frame[1] |= (ax25->vr << 1);
0234 }
0235
0236 ax25_start_idletimer(ax25);
0237
0238 ax25_transmit_buffer(ax25, skb, AX25_COMMAND);
0239 }
0240
0241 void ax25_kick(ax25_cb *ax25)
0242 {
0243 struct sk_buff *skb, *skbn;
0244 int last = 1;
0245 unsigned short start, end, next;
0246
0247 if (ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4)
0248 return;
0249
0250 if (ax25->condition & AX25_COND_PEER_RX_BUSY)
0251 return;
0252
0253 if (skb_peek(&ax25->write_queue) == NULL)
0254 return;
0255
0256 start = (skb_peek(&ax25->ack_queue) == NULL) ? ax25->va : ax25->vs;
0257 end = (ax25->va + ax25->window) % ax25->modulus;
0258
0259 if (start == end)
0260 return;
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272 skb = skb_dequeue(&ax25->write_queue);
0273 if (!skb)
0274 return;
0275
0276 ax25->vs = start;
0277
0278 do {
0279 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
0280 skb_queue_head(&ax25->write_queue, skb);
0281 break;
0282 }
0283
0284 if (skb->sk != NULL)
0285 skb_set_owner_w(skbn, skb->sk);
0286
0287 next = (ax25->vs + 1) % ax25->modulus;
0288 last = (next == end);
0289
0290
0291
0292
0293
0294
0295 switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
0296 case AX25_PROTO_STD_SIMPLEX:
0297 case AX25_PROTO_STD_DUPLEX:
0298 ax25_send_iframe(ax25, skbn, (last) ? AX25_POLLON : AX25_POLLOFF);
0299 break;
0300
0301 #ifdef CONFIG_AX25_DAMA_SLAVE
0302 case AX25_PROTO_DAMA_SLAVE:
0303 ax25_send_iframe(ax25, skbn, AX25_POLLOFF);
0304 break;
0305 #endif
0306 }
0307
0308 ax25->vs = next;
0309
0310
0311
0312
0313 skb_queue_tail(&ax25->ack_queue, skb);
0314
0315 } while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
0316
0317 ax25->condition &= ~AX25_COND_ACK_PENDING;
0318
0319 if (!ax25_t1timer_running(ax25)) {
0320 ax25_stop_t3timer(ax25);
0321 ax25_calculate_t1(ax25);
0322 ax25_start_t1timer(ax25);
0323 }
0324 }
0325
0326 void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
0327 {
0328 unsigned char *ptr;
0329 int headroom;
0330
0331 if (ax25->ax25_dev == NULL) {
0332 ax25_disconnect(ax25, ENETUNREACH);
0333 return;
0334 }
0335
0336 headroom = ax25_addr_size(ax25->digipeat);
0337
0338 if (unlikely(skb_headroom(skb) < headroom)) {
0339 skb = skb_expand_head(skb, headroom);
0340 if (!skb) {
0341 printk(KERN_CRIT "AX.25: ax25_transmit_buffer - out of memory\n");
0342 return;
0343 }
0344 }
0345
0346 ptr = skb_push(skb, headroom);
0347
0348 ax25_addr_build(ptr, &ax25->source_addr, &ax25->dest_addr, ax25->digipeat, type, ax25->modulus);
0349
0350 ax25_queue_xmit(skb, ax25->ax25_dev->dev);
0351 }
0352
0353
0354
0355
0356
0357 void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev)
0358 {
0359 unsigned char *ptr;
0360
0361 skb->protocol = ax25_type_trans(skb, ax25_fwd_dev(dev));
0362
0363 ptr = skb_push(skb, 1);
0364 *ptr = 0x00;
0365
0366 dev_queue_xmit(skb);
0367 }
0368
0369 int ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr)
0370 {
0371 if (ax25->vs == nr) {
0372 ax25_frames_acked(ax25, nr);
0373 ax25_calculate_rtt(ax25);
0374 ax25_stop_t1timer(ax25);
0375 ax25_start_t3timer(ax25);
0376 return 1;
0377 } else {
0378 if (ax25->va != nr) {
0379 ax25_frames_acked(ax25, nr);
0380 ax25_calculate_t1(ax25);
0381 ax25_start_t1timer(ax25);
0382 return 1;
0383 }
0384 }
0385 return 0;
0386 }