patch-1.3.73 linux/net/ax25/ax25_in.c
Next file: linux/net/ax25/ax25_out.c
Previous file: linux/net/ax25/af_ax25.c
Back to the patch index
Back to the overall index
- Lines: 202
- Date:
Sun Mar 10 09:28:57 1996
- Orig file:
v1.3.72/linux/net/ax25/ax25_in.c
- Orig date:
Fri Feb 23 13:54:41 1996
diff -u --recursive --new-file v1.3.72/linux/net/ax25/ax25_in.c linux/net/ax25/ax25_in.c
@@ -28,6 +28,10 @@
* Upgraded state machine for SABME.
* Added arbitrary protocol id support.
* AX.25 031 Joerg(DL1BKE) Added DAMA support
+ * HaJo(DD8NE) Added Idle Disc Timer T5
+ * Joerg(DL1BKE) renamed it to "IDLE" with a slightly
+ * different behaviour. Fixed defrag
+ * routine (I hope)
*/
#include <linux/config.h>
@@ -71,10 +75,15 @@
if (ax25->fragno != 0) {
if (!(*skb->data & SEG_FIRST)) {
if ((ax25->fragno - 1) == (*skb->data & SEG_REM)) {
+
+ /* enqueue fragment */
+
ax25->fragno = *skb->data & SEG_REM;
- skb_pull(skb, 1);
+ skb_pull(skb, 1); /* skip fragno */
ax25->fraglen += skb->len;
skb_queue_tail(&ax25->frag_queue, skb);
+
+ /* last fragment received? */
if (ax25->fragno == 0) {
if ((skbn = alloc_skb(AX25_MAX_HEADER_LEN + ax25->fraglen, GFP_ATOMIC)) == NULL)
@@ -82,28 +91,45 @@
skbn->free = 1;
skbn->arp = 1;
+ skbn->dev = skb->dev;
if (ax25->sk != NULL) {
skbn->sk = ax25->sk;
ax25->sk->rmem_alloc += skbn->truesize;
}
- skb_reserve(skbn, AX25_MAX_HEADER_LEN);
- skbn->h.raw = skbn->data;
-
+ /* get first fragment from queue */
+
skbo = skb_dequeue(&ax25->frag_queue);
- hdrlen = skbo->data - skbo->h.raw;
- skb_push(skbo, hdrlen);
+ hdrlen = skbo->data - skbo->h.raw - 2; /* skip PID & fragno */
+
+ skb_push(skbo, hdrlen + 2); /* start of address field */
+ skbn->data = skb_put(skbn, hdrlen); /* get space for info */
+ memcpy(skbn->data, skbo->data, hdrlen); /* copy address field */
+ skb_pull(skbo, hdrlen + 2); /* start of data */
+ skb_pull(skbn, hdrlen + 1); /* dito */
+
+ /* copy data from first fragment */
+
memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
- skb_pull(skbn, hdrlen);
kfree_skb(skbo, FREE_READ);
+
+ /* add other fragment's data */
while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) {
memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
kfree_skb(skbo, FREE_READ);
}
- ax25->fraglen = 0;
+ ax25->fraglen = 0; /* reset counter */
+
+ /*
+ * mysteriously we need to re-adjust skb->data.
+ * Anyway, it seems to work. Do we have the address fields
+ * encoded TWICE in one sk_buff?
+ */
+
+ skb_pull(skbn, hdrlen);
if (ax25_rx_iframe(ax25, skbn) == 0)
kfree_skb(skbn, FREE_READ);
@@ -113,9 +139,11 @@
}
}
} else {
+ /* first fragment received? */
+
if (*skb->data & SEG_FIRST) {
ax25->fragno = *skb->data & SEG_REM;
- skb_pull(skb, 1);
+ skb_pull(skb, 1); /* skip fragno */
ax25->fraglen = skb->len;
skb_queue_tail(&ax25->frag_queue, skb);
return 1;
@@ -141,6 +169,7 @@
switch (pid) {
#ifdef CONFIG_NETROM
case AX25_P_NETROM:
+ ax25->idletimer = ax25->idle = ax25_dev_get_value(ax25->device, AX25_VALUES_IDLE);
if (ax25_dev_get_value(ax25->device, AX25_VALUES_NETROM)) {
skb_pull(skb, 1); /* Remove PID */
queued = nr_route_frame(skb, ax25);
@@ -149,6 +178,7 @@
#endif
#ifdef CONFIG_INET
case AX25_P_IP:
+ ax25->idletimer = ax25->idle = ax25_dev_get_value(ax25->device, AX25_VALUES_IDLE);
skb_pull(skb, 1); /* Remove PID */
skb->h.raw = skb->data;
ax25_ip_mode_set(&ax25->dest_addr, ax25->device, 'V');
@@ -158,11 +188,13 @@
break;
#endif
case AX25_P_SEGMENT:
+ ax25->idletimer = ax25->idle = ax25_dev_get_value(ax25->device, AX25_VALUES_IDLE);
skb_pull(skb, 1); /* Remove PID */
queued = ax25_rx_fragment(ax25, skb);
break;
default:
+ ax25->idletimer = ax25->idle = 0;
if (ax25->sk != NULL && ax25_dev_get_value(ax25->device, AX25_VALUES_TEXT) && ax25->sk->protocol == pid) {
if (sock_queue_rcv_skb(ax25->sk, skb) == 0) {
queued = 1;
@@ -207,6 +239,7 @@
ax25_calculate_rtt(ax25);
ax25->t1timer = 0;
ax25->t3timer = ax25->t3;
+ ax25->idletimer = ax25->idle;
ax25->vs = 0;
ax25->va = 0;
ax25->vr = 0;
@@ -353,6 +386,7 @@
ax25->condition = 0x00;
ax25->t1timer = 0;
ax25->t3timer = ax25->t3;
+ ax25->idletimer = ax25->idle;
ax25->vs = 0;
ax25->va = 0;
ax25->vr = 0;
@@ -368,6 +402,7 @@
ax25->condition = 0x00;
ax25->t1timer = 0;
ax25->t3timer = ax25->t3;
+ ax25->idletimer = ax25->idle;
ax25->vs = 0;
ax25->va = 0;
ax25->vr = 0;
@@ -546,6 +581,7 @@
ax25->condition = 0x00;
ax25->t1timer = 0;
ax25->t3timer = ax25->t3;
+ ax25->idletimer = ax25->idle;
ax25->vs = 0;
ax25->va = 0;
ax25->vr = 0;
@@ -563,6 +599,7 @@
ax25->condition = 0x00;
ax25->t1timer = 0;
ax25->t3timer = ax25->t3;
+ ax25->idletimer = ax25->idle;
ax25->vs = 0;
ax25->va = 0;
ax25->vr = 0;
@@ -620,8 +657,6 @@
}
break;
}
- /* dl1bke 960114: replaced if(..) ax25_enquiry_response */
- /* with ax25_check_need_response() */
ax25_check_need_response(ax25, type, pf);
if (ax25_validate_nr(ax25, nr)) {
@@ -654,10 +689,10 @@
break;
}
- ax25_check_need_response(ax25, type, pf); /* dl1bke 960114 */
+ ax25_check_need_response(ax25, type, pf);
if (ax25_validate_nr(ax25, nr)) {
ax25_frames_acked(ax25, nr);
- dama_check_need_response(ax25, type, pf); /* dl1bke 960114 */
+ dama_check_need_response(ax25, type, pf);
} else {
ax25_nr_error_recovery(ax25);
ax25->state = AX25_STATE_1;
@@ -685,13 +720,13 @@
break;
}
- ax25_check_need_response(ax25, type, pf); /* dl1bke 960114 */
+ ax25_check_need_response(ax25, type, pf);
if (ax25_validate_nr(ax25, nr)) {
ax25_frames_acked(ax25, nr);
if(ax25->vs != ax25->va) {
ax25_requeue_frames(ax25);
}
- dama_check_need_response(ax25, type, pf); /* dl1bke 960114 */
+ dama_check_need_response(ax25, type, pf);
} else {
ax25_nr_error_recovery(ax25);
ax25->state = AX25_STATE_1;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this