patch-1.3.14 linux/net/ax25/af_ax25.c
Next file: linux/net/ax25/ax25_in.c
Previous file: linux/net/appletalk/ddp.c
Back to the patch index
Back to the overall index
- Lines: 304
- Date:
Mon Jul 31 09:46:26 1995
- Orig file:
v1.3.13/linux/net/ax25/af_ax25.c
- Orig date:
Fri Jul 7 08:54:56 1995
diff -u --recursive --new-file v1.3.13/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
@@ -1,5 +1,5 @@
/*
- * AX.25 release 029
+ * AX.25 release 030
*
* This is ALPHA test software. This code may break your machine, randomly fail to work with new
* releases, misbehave and/or generally screw up. It might even work.
@@ -58,7 +58,9 @@
* Alan(GW4PTS) Missed suser() on axassociate checks
* AX.25 030 Alan(GW4PTS) Added variable length headers.
* Jonathan(G4KLX) Added BPQ Ethernet interface.
- * Steven(GW7RRM)
+ * Steven(GW7RRM) Added digi-peating control ioctl.
+ * Added extended AX.25 support.
+ * Added AX.25 frame segmentation.
*
* To do:
* Support use as digipeater, including an on/off ioctl
@@ -98,6 +100,8 @@
#include <net/ip.h>
#include <net/arp.h>
+static int ax25_digi_on = 1;
+
#define CONFIG_AX25_XDIGI /* Cross port (band) digi stuff */
/**********************************************************************************************************************\
@@ -197,6 +201,7 @@
for (s = ax25_list; s != NULL; s = s->next) {
if (s->device == dev) {
+ s->state = AX25_STATE_0;
s->device = NULL;
if (s->sk != NULL) {
s->sk->state = TCP_CLOSE;
@@ -388,7 +393,7 @@
del_timer(&ax25->timer);
ax25_remove_socket(ax25);
- ax25_clear_tx_queue(ax25); /* Flush the send queue */
+ ax25_clear_queues(ax25); /* Flush the queues */
if (ax25->sk != NULL) {
while ((skb = skb_dequeue(&ax25->sk->receive_queue)) != NULL) {
@@ -410,7 +415,7 @@
if (ax25->sk != NULL) {
if (ax25->sk->wmem_alloc || ax25->sk->rmem_alloc) { /* Defer: outstanding buffers */
init_timer(&ax25->timer);
- ax25->timer.expires = 10 * HZ;
+ ax25->timer.expires = jiffies + 10 * HZ;
ax25->timer.function = ax25_destroy_timer;
ax25->timer.data = (unsigned long)ax25;
add_timer(&ax25->timer);
@@ -502,7 +507,9 @@
return NULL;
skb_queue_head_init(&ax25->write_queue);
+ skb_queue_head_init(&ax25->frag_queue);
skb_queue_head_init(&ax25->ack_queue);
+ skb_queue_head_init(&ax25->reseq_queue);
init_timer(&ax25->timer);
@@ -512,6 +519,9 @@
ax25->n2 = DEFAULT_N2;
ax25->t3 = DEFAULT_T3;
+ ax25->modulus = MODULUS;
+ ax25->fragno = 0;
+ ax25->fraglen = 0;
ax25->backoff = 1;
ax25->condition = 0x00;
ax25->t1timer = 0;
@@ -656,8 +666,13 @@
switch (optname) {
case AX25_WINDOW:
- if (opt < 1 || opt > 7)
- return -EINVAL;
+ if (sk->ax25->modulus == MODULUS) {
+ if (opt < 1 || opt > 7)
+ return -EINVAL;
+ } else {
+ if (opt < 1 || opt > 63)
+ return -EINVAL;
+ }
sk->ax25->window = opt;
return 0;
@@ -689,6 +704,10 @@
sk->ax25->backoff = opt ? 1 : 0;
return 0;
+ case AX25_EXTSEQ:
+ sk->ax25->modulus = opt ? EMODULUS : MODULUS;
+ return 0;
+
default:
return -ENOPROTOOPT;
}
@@ -734,6 +753,10 @@
val = sk->ax25->backoff;
break;
+ case AX25_EXTSEQ:
+ val = (sk->ax25->modulus == EMODULUS);
+ return 0;
+
default:
return -ENOPROTOOPT;
}
@@ -907,6 +930,7 @@
sk->write_space = def_callback1;
sk->error_report = def_callback1;
+ ax25->modulus = osk->ax25->modulus;
ax25->backoff = osk->ax25->backoff;
ax25->rtt = osk->ax25->rtt;
ax25->t1 = osk->ax25->t1;
@@ -955,7 +979,7 @@
break;
case AX25_STATE_1:
- ax25_send_control(sk->ax25, DISC | PF, C_COMMAND);
+ ax25_send_control(sk->ax25, DISC, POLLON, C_COMMAND);
sk->ax25->state = AX25_STATE_0;
sk->dead = 1;
sk->state_change(sk);
@@ -963,7 +987,7 @@
break;
case AX25_STATE_2:
- ax25_send_control(sk->ax25, DM | PF, C_RESPONSE);
+ ax25_send_control(sk->ax25, DM, POLLON, C_RESPONSE);
sk->ax25->state = AX25_STATE_0;
sk->dead = 1;
sk->state_change(sk);
@@ -972,9 +996,9 @@
case AX25_STATE_3:
case AX25_STATE_4:
- ax25_clear_tx_queue(sk->ax25);
+ ax25_clear_queues(sk->ax25);
sk->ax25->n2count = 0;
- ax25_send_control(sk->ax25, DISC | PF, C_COMMAND);
+ ax25_send_control(sk->ax25, DISC, POLLON, C_COMMAND);
sk->ax25->t3timer = 0;
sk->ax25->t1timer = sk->ax25->t1 = ax25_calculate_t1(sk->ax25);
sk->ax25->state = AX25_STATE_2;
@@ -1306,9 +1330,13 @@
dev = dev_scan;
}
#endif
- build_ax25_addr(skb->data, &src, &dest, &dp, type);
+ build_ax25_addr(skb->data, &src, &dest, &dp, type, MODULUS);
skb->arp = 1;
- ax25_queue_xmit(skb, dev, SOPRI_NORMAL);
+ if (ax25_digi_on) {
+ ax25_queue_xmit(skb, dev, SOPRI_NORMAL);
+ } else {
+ kfree_skb(skb, FREE_READ);
+ }
} else {
kfree_skb(skb, FREE_READ);
}
@@ -1398,12 +1426,12 @@
return 0;
}
- if ((*skb->data & 0xEF) != SABM) {
+ if ((*skb->data & ~PF) != SABM && (*skb->data & ~PF) != SABME) {
/*
* Never reply to a DM. Also ignore any connects for
* addresses that are not our interfaces and not a socket.
*/
- if ((*skb->data & 0xEF) != DM && mine)
+ if ((*skb->data & ~PF) != DM && mine)
ax25_return_dm(dev, &src, &dest, &dp);
kfree_skb(skb, FREE_READ);
@@ -1471,9 +1499,15 @@
ax25_digi_invert(&dp, ax25->digipeat);
}
+ if ((*skb->data & ~PF) == SABME) {
+ ax25->modulus = EMODULUS;
+ } else {
+ ax25->modulus = MODULUS;
+ }
+
ax25->device = dev;
- ax25_send_control(ax25, UA | PF, C_RESPONSE);
+ ax25_send_control(ax25, UA, POLLON, C_RESPONSE);
ax25->t3timer = ax25->t3;
ax25->state = AX25_STATE_3;
@@ -1524,10 +1558,10 @@
return 0;
}
- len = skb->data[14] + skb->data[15] * 256 - 5;
+ len = skb->data[0] + skb->data[1] * 256 - 5;
- skb_pull(skb, AX25_BPQ_HEADER_LEN); /* Remove the BPQ Header */
- skb_trim(skb, len); /* Set the length of the data */
+ skb_pull(skb, 2); /* Remove the length bytes */
+ skb_trim(skb, len); /* Set the length of the data */
return ax25_rcv(skb, dev, &port_call, ptype);
}
@@ -1618,7 +1652,7 @@
printk("AX.25: sendto: building packet.\n");
/* Assume the worst case */
- size = len + 2 + size_ax25_addr(dp) + AX25_BPQ_HEADER_LEN;
+ size = len + 3 + size_ax25_addr(dp) + AX25_BPQ_HEADER_LEN;
if ((skb = sock_alloc_send_skb(sk, size, 0, &err)) == NULL)
return err;
@@ -1662,7 +1696,7 @@
}
/* Build an AX.25 header */
- asmptr += (lv = build_ax25_addr(asmptr, &sk->ax25->source_addr, &sax.sax25_call, dp, C_COMMAND));
+ asmptr += (lv = build_ax25_addr(asmptr, &sk->ax25->source_addr, &sax.sax25_call, dp, C_COMMAND, MODULUS));
if (sk->debug)
printk("Built header (%d bytes)\n",lv);
@@ -1716,7 +1750,7 @@
if (sk->type == SOCK_SEQPACKET) {
if (sk->state != TCP_ESTABLISHED)
return -ENOTCONN;
- bias = 2;
+ bias = 1;
}
/* Now we can treat all alike */
@@ -1843,6 +1877,15 @@
ax25_uid_policy = amount;
return 0;
+ case SIOCAX25DIGCTL:
+ if ((err = verify_area(VERIFY_READ, (void *)arg, sizeof(int))) != 0)
+ return err;
+ if (!suser())
+ return -EPERM;
+ amount = get_fs_long((void *)arg);
+ ax25_digi_on = amount ? 1 : 0;
+ return 0;
+
case SIOCGIFADDR:
case SIOCSIFADDR:
case SIOCGIFDSTADDR:
@@ -1874,7 +1917,7 @@
cli();
- len += sprintf(buffer, "dest_addr src_addr dev st vs vr va t1 t2 t3 n2 rtt wnd Snd-Q Rcv-Q\n");
+ len += sprintf(buffer, "dest_addr src_addr dev st vs vr va t1 t2 t3 n2 rtt wnd Snd-Q Rcv-Q\n");
for (ax25 = ax25_list; ax25 != NULL; ax25 = ax25->next) {
if ((dev = ax25->device) == NULL)
@@ -1884,7 +1927,7 @@
len += sprintf(buffer + len, "%-9s ",
ax2asc(&ax25->dest_addr));
- len += sprintf(buffer + len, "%-9s %-4s %2d %2d %2d %2d %3d/%03d %2d/%02d %3d/%03d %2d/%02d %3d %3d",
+ len += sprintf(buffer + len, "%-9s %-4s %2d %3d %3d %3d %3d/%03d %2d/%02d %3d/%03d %2d/%02d %3d %3d",
ax2asc(&ax25->source_addr), devname,
ax25->state,
ax25->vs, ax25->vr, ax25->va,
@@ -2050,7 +2093,7 @@
buff[6] &= ~LAPB_C;
buff[6] &= ~LAPB_E;
- buff[6] |= SSID_SPARE;
+ buff[6] |= SSSID_SPARE;
buff += AX25_ADDR_LEN;
if (saddr != NULL)
@@ -2060,7 +2103,7 @@
buff[6] &= ~LAPB_C;
buff[6] |= LAPB_E;
- buff[6] |= SSID_SPARE;
+ buff[6] |= SSSID_SPARE;
buff += AX25_ADDR_LEN;
*buff++ = LAPB_UI; /* UI */
@@ -2105,11 +2148,11 @@
bp[7] &= ~LAPB_C;
bp[7] &= ~LAPB_E;
- bp[7] |= SSID_SPARE;
+ bp[7] |= SSSID_SPARE;
bp[14] &= ~LAPB_C;
bp[14] |= LAPB_E;
- bp[14] |= SSID_SPARE;
+ bp[14] |= SSSID_SPARE;
return 0;
}
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