diff -u --recursive --new-file linux-2.1.30/Makefile linux/Makefile --- linux-2.1.30/Makefile Thu Mar 27 19:42:57 1997 +++ linux/Makefile Thu Mar 27 19:45:01 1997 @@ -11,7 +11,7 @@ # # NOTE! SMP is experimental. See the file Documentation/SMP.txt # -SMP = 1 +# SMP = 1 # # SMP profiling options # SMP_PROF = 1 diff -u --recursive --new-file linux-2.1.30/drivers/net/bpqether.c linux/drivers/net/bpqether.c --- linux-2.1.30/drivers/net/bpqether.c Thu Mar 27 19:43:06 1997 +++ linux/drivers/net/bpqether.c Thu Mar 20 19:08:45 1997 @@ -1,10 +1,6 @@ /* * G8BPQ compatible "AX.25 via ethernet" driver release 003 * - * 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. - * * This code REQUIRES 2.0.0 or higher/ NET3.029 * * This module: @@ -266,6 +262,7 @@ */ static int bpq_xmit(struct sk_buff *skb, struct device *dev) { + struct sk_buff *newskb; unsigned char *ptr; struct bpqdev *bpq; int size; @@ -276,7 +273,7 @@ */ if (!dev->start) { bpq_check_devices(dev); - dev_kfree_skb(skb, FREE_WRITE); + kfree_skb(skb, FREE_WRITE); return -ENODEV; } @@ -288,21 +285,16 @@ * sendto() does not. */ if (skb_headroom(skb) < AX25_BPQ_HEADER_LEN) { /* Ough! */ - struct sk_buff *newskb = alloc_skb(skb->len + AX25_BPQ_HEADER_LEN, GFP_ATOMIC); - - if (newskb == NULL) { /* Argh! */ - printk(KERN_WARNING "bpq_xmit: not enough space to add BPQ Ether header\n"); - dev_kfree_skb(skb, FREE_WRITE); + if ((newskb = skb_realloc_headroom(skb, AX25_BPQ_HEADER_LEN)) == NULL) { + printk(KERN_WARNING "bpqether: out of memory\n"); + kfree_skb(skb, FREE_WRITE); return -ENOMEM; } - newskb->arp = 1; - if (skb->sk) + if (skb->sk != NULL) skb_set_owner_w(newskb, skb->sk); - skb_reserve(newskb, AX25_BPQ_HEADER_LEN); - memcpy(skb_put(newskb, size), skb->data, size); - dev_kfree_skb(skb, FREE_WRITE); + kfree_skb(skb, FREE_WRITE); skb = newskb; } @@ -318,7 +310,7 @@ if ((dev = bpq_get_ether_dev(dev)) == NULL) { bpq->stats.tx_dropped++; - dev_kfree_skb(skb, FREE_WRITE); + kfree_skb(skb, FREE_WRITE); return -ENODEV; } @@ -506,7 +498,7 @@ unsigned char *buf; struct bpqdev *bpq, *bpq2; - if ((bpq = (struct bpqdev *)kmalloc(sizeof(struct bpqdev), GFP_KERNEL)) == NULL) + if ((bpq = kmalloc(sizeof(struct bpqdev), GFP_KERNEL)) == NULL) return -ENOMEM; memset(bpq, 0, sizeof(struct bpqdev)); @@ -520,7 +512,7 @@ memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr)); dev = &bpq->axdev; - buf = (unsigned char *)kmalloc(14, GFP_KERNEL); + buf = kmalloc(14, GFP_KERNEL); for (k = 0; k < MAXBPQDEV; k++) { struct device *odev; @@ -660,6 +652,9 @@ #ifdef MODULE EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Joerg Reuter DL1BKE "); +MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet"); int init_module(void) { diff -u --recursive --new-file linux-2.1.30/drivers/net/lapbether.c linux/drivers/net/lapbether.c --- linux-2.1.30/drivers/net/lapbether.c Thu Mar 27 19:43:07 1997 +++ linux/drivers/net/lapbether.c Thu Mar 20 20:06:13 1997 @@ -1,10 +1,6 @@ /* * "LAPB via ethernet" driver release 001 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -225,7 +221,7 @@ */ if (!dev->start) { lapbeth_check_devices(dev); - dev_kfree_skb(skb, FREE_WRITE); + kfree_skb(skb, FREE_WRITE); return -ENODEV; } @@ -426,7 +422,7 @@ unsigned char *buf; struct lapbethdev *lapbeth, *lapbeth2; - if ((lapbeth = (struct lapbethdev *)kmalloc(sizeof(struct lapbethdev), GFP_KERNEL)) == NULL) + if ((lapbeth = kmalloc(sizeof(struct lapbethdev), GFP_KERNEL)) == NULL) return -ENOMEM; memset(lapbeth, 0, sizeof(struct lapbethdev)); @@ -437,7 +433,7 @@ strncpy(lapbeth->ethname, dev->name, sizeof(lapbeth->ethname)-1); dev = &lapbeth->axdev; - buf = (unsigned char *)kmalloc(14, GFP_KERNEL); + buf = kmalloc(14, GFP_KERNEL); for (k = 0; k < MAXLAPBDEV; k++) { struct device *odev; @@ -560,6 +556,9 @@ #ifdef MODULE EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Jonathan Naylor "); +MODULE_DESCRIPTION("The unofficial LAPB over Ethernet driver"); int init_module(void) { diff -u --recursive --new-file linux-2.1.30/drivers/net/mkiss.c linux/drivers/net/mkiss.c --- linux-2.1.30/drivers/net/mkiss.c Thu Mar 27 19:43:08 1997 +++ linux/drivers/net/mkiss.c Thu Mar 20 19:19:11 1997 @@ -117,7 +117,7 @@ return NULL; /* If no channels are available, allocate one */ - if (axp == NULL && (ax25_ctrls[i] = (ax25_ctrl_t *)kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) { + if (axp == NULL && (ax25_ctrls[i] = kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) { axp = ax25_ctrls[i]; memset(axp, 0, sizeof(ax25_ctrl_t)); @@ -147,7 +147,7 @@ return &axp->ctrl; } else { clear_bit(AXF_INUSE,&axp->ctrl.flags); - printk(KERN_ERR "ax_alloc() - register_netdev() failure.\n"); + printk(KERN_ERR "mkiss: ax_alloc() - register_netdev() failure.\n"); } } @@ -165,7 +165,7 @@ kfree(ax->xbuff); ax->xbuff = NULL; if (!clear_bit(AXF_INUSE, &ax->flags)) - printk(KERN_ERR "%s: ax_free for already free unit.\n", ax->dev->name); + printk(KERN_ERR "mkiss: %s: ax_free for already free unit.\n", ax->dev->name); } static void ax_changedmtu(struct ax_disp *ax) @@ -185,11 +185,11 @@ if (len < 576 * 2) len = 576 * 2; - xbuff = (unsigned char *)kmalloc(len + 4, GFP_ATOMIC); - rbuff = (unsigned char *)kmalloc(len + 4, GFP_ATOMIC); + xbuff = kmalloc(len + 4, GFP_ATOMIC); + rbuff = kmalloc(len + 4, GFP_ATOMIC); if (xbuff == NULL || rbuff == NULL) { - printk(KERN_ERR "%s: unable to grow ax25 buffers, MTU change cancelled.\n", + printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, MTU change cancelled.\n", ax->dev->name); dev->mtu = ax->mtu; if (xbuff != NULL) @@ -244,7 +244,7 @@ static inline void ax_lock(struct ax_disp *ax) { if (set_bit(0, (void *)&ax->dev->tbusy)) - printk(KERN_ERR "%s: trying to lock already locked device!\n", ax->dev->name); + printk(KERN_ERR "mkiss: %s: trying to lock already locked device!\n", ax->dev->name); } @@ -252,7 +252,7 @@ static inline void ax_unlock(struct ax_disp *ax) { if (!clear_bit(0, (void *)&ax->dev->tbusy)) - printk(KERN_ERR "%s: trying to unlock already unlocked device!\n", ax->dev->name); + printk(KERN_ERR "mkiss: %s: trying to unlock already unlocked device!\n", ax->dev->name); } /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ @@ -276,7 +276,7 @@ count = ax->rcount; if ((skb = dev_alloc_skb(count)) == NULL) { - printk(KERN_ERR "%s: memory squeeze, dropping packet.\n", ax->dev->name); + printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name); ax->rx_dropped++; return; } @@ -301,7 +301,7 @@ if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */ len = ax->mtu; - printk(KERN_ERR "%s: truncating oversized transmit packet!\n", ax->dev->name); + printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name); ax->tx_dropped++; ax_unlock(ax); return; @@ -379,7 +379,7 @@ } if (!dev->start) { - printk(KERN_ERR "%s: xmit call when iface is down\n", dev->name); + printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); return 1; } @@ -403,7 +403,7 @@ return 1; } - printk(KERN_ERR "%s: transmit timed out, %s?\n", dev->name, + printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name, (ax->tty->driver.chars_in_buffer(ax->tty) || ax->xleft) ? "bad line quality" : "driver error"); @@ -418,7 +418,7 @@ if (tmp_ax != NULL) ax_lock(tmp_ax); ax_encaps(ax, skb->data, skb->len); - dev_kfree_skb(skb, FREE_WRITE); + kfree_skb(skb, FREE_WRITE); } return 0; @@ -475,10 +475,10 @@ if (len < 576 * 2) len = 576 * 2; - if ((ax->rbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL)) == NULL) + if ((ax->rbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL) goto norbuff; - if ((ax->xbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL)) == NULL) + if ((ax->xbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL) goto noxbuff; ax->mtu = dev->mtu + 73; @@ -822,7 +822,7 @@ if (ax25_maxdev < 4) ax25_maxdev = 4; /* Sanity */ - if ((ax25_ctrls = (ax25_ctrl_t **)kmalloc(sizeof(void*) * ax25_maxdev, GFP_KERNEL)) == NULL) { + if ((ax25_ctrls = kmalloc(sizeof(void*) * ax25_maxdev, GFP_KERNEL)) == NULL) { printk(KERN_ERR "mkiss: Can't allocate ax25_ctrls[] array ! No mkiss available\n"); return -ENOMEM; } @@ -1079,7 +1079,7 @@ mkiss_driver.put_char = mkiss_dummy2; if (tty_register_driver(&mkiss_driver)) { - printk(KERN_ERR "Couldn't register Mkiss device\n"); + printk(KERN_ERR "mkiss: couldn't register Mkiss device\n"); return -EIO; } @@ -1090,6 +1090,9 @@ #ifdef MODULE EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Hans Albas PE1AYX "); +MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs"); int init_module(void) { diff -u --recursive --new-file linux-2.1.30/drivers/net/pi2.c linux/drivers/net/pi2.c --- linux-2.1.30/drivers/net/pi2.c Thu Mar 27 19:43:08 1997 +++ linux/drivers/net/pi2.c Thu Mar 20 19:14:19 1997 @@ -331,11 +331,6 @@ wrtscc(lp->cardbase, lp->base + CTL, R0, RES_EXT_INT); } -static void free_p(struct sk_buff *skb) -{ - dev_kfree_skb(skb, FREE_WRITE); -} - static void a_txint(struct pi_local *lp) { int cmd; @@ -412,7 +407,7 @@ } switch (lp->tstate) { case ACTIVE: - free_p(lp->sndbuf); + kfree_skb(lp->sndbuf, FREE_WRITE); lp->sndbuf = NULL; lp->tstate = FLAGOUT; tdelay(lp, lp->squeldelay); @@ -732,7 +727,7 @@ /* stuffing a char satisfies Interrupt condition */ } else { /* No more to send */ - free_p(lp->sndbuf); + kfree_skb(lp->sndbuf, FREE_WRITE); lp->sndbuf = NULL; if ((rdscc(lp->cardbase, cmd, R0) & 0x40)) { /* Did we underrun? */ @@ -784,7 +779,7 @@ switch (lp->tstate) { case ACTIVE: /* Unexpected underrun */ - free_p(lp->sndbuf); + kfree_skb(lp->sndbuf, FREE_WRITE); lp->sndbuf = NULL; wrtscc(lp->cardbase, cmd, R0, SEND_ABORT); lp->tstate = FLAGOUT; @@ -1574,7 +1569,7 @@ /* Free any buffers left in the hardware transmit queue */ while ((ptr = skb_dequeue(&lp->sndq)) != NULL) - free_p(ptr); + kfree_skb(ptr, FREE_WRITE); restore_flags(flags); @@ -1674,6 +1669,9 @@ #ifdef MODULE EXPORT_NO_SYMBOLS; +MODULE_AUTHOR("David Perry"); +MODULE_DESCRIPTION("AX.25 driver for the Ottawa PI and PI/2 HDLC cards"); + int init_module(void) { return pi_init(); @@ -1694,12 +1692,3 @@ unregister_netdev(&pi0b); } #endif - -/* - * Local variables: - * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c" - * version-control: t - * kept-new-versions: 5 - * tab-width: 4 - * End: - */ diff -u --recursive --new-file linux-2.1.30/drivers/net/pt.c linux/drivers/net/pt.c --- linux-2.1.30/drivers/net/pt.c Thu Mar 27 19:43:08 1997 +++ linux/drivers/net/pt.c Thu Mar 20 20:08:47 1997 @@ -26,7 +26,7 @@ * 03/03/95 cs Painfully found out (after 3 days) SERIAL_CFG is write only * created image of it and DMA_CFG * 21/06/95 cs Upgraded to suit PI driver 0.8 ALPHA - * 22/08/95 cs Changed it all around to make it like pi driver + * 22/08/95 cs Changed it all around to make it like pi driver * 23/08/95 cs It now works, got caught again by TMR2 and we must have * auto-enables for daughter boards. * 07/10/95 cs Fixed for 1.3.30 (hopefully) @@ -317,12 +317,6 @@ restore_flags(flags); } -static void free_p(struct sk_buff *skb) -{ - dev_kfree_skb(skb, FREE_WRITE); -} - - /* * This sets up all the registers in the SCC for the given channel * based upon tsync_hwint() @@ -985,7 +979,7 @@ /* Free any buffers left in the hardware transmit queue */ while ((ptr = skb_dequeue(&lp->sndq)) != NULL) - free_p(ptr); + kfree_skb(ptr, FREE_WRITE); restore_flags(flags); @@ -1203,7 +1197,7 @@ /* stuffing a char satisfies interrupt condition */ } else { /* No more to send */ - free_p(lp->sndbuf); + kfree_skb(lp->sndbuf, FREE_WRITE); lp->sndbuf = NULL; if ((rdscc(lp->cardbase, cmd, R0) & TxEOM)) { @@ -1559,7 +1553,7 @@ #ifdef PT_DEBUG printk(KERN_DEBUG "PT: exisr(): unexpected underrun detected.\n"); #endif - free_p(lp->sndbuf); + kfree_skb(lp->sndbuf, FREE_WRITE); lp->sndbuf = NULL; if (!lp->dmachan) { @@ -1772,6 +1766,9 @@ #ifdef MODULE EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Craig Small VK2XLZ "); +MODULE_DESCRIPTION("AX.25 driver for the Gracillis PacketTwin HDLC card"); int init_module(void) { diff -u --recursive --new-file linux-2.1.30/drivers/net/soundmodem/sm.c linux/drivers/net/soundmodem/sm.c --- linux-2.1.30/drivers/net/soundmodem/sm.c Thu Mar 27 19:43:09 1997 +++ linux/drivers/net/soundmodem/sm.c Wed Mar 26 15:04:30 1997 @@ -157,6 +157,7 @@ static const struct hardware_info *sm_hardware_table[] = { #ifdef CONFIG_SOUNDMODEM_SBC &sm_hw_sbc, + &sm_hw_sbcfdx, #endif /* CONFIG_SOUNDMODEM_SBC */ #ifdef CONFIG_SOUNDMODEM_WSS &sm_hw_wss, diff -u --recursive --new-file linux-2.1.30/drivers/net/soundmodem/sm.h linux/drivers/net/soundmodem/sm.h --- linux-2.1.30/drivers/net/soundmodem/sm.h Fri Mar 7 14:49:04 1997 +++ linux/drivers/net/soundmodem/sm.h Wed Mar 26 15:05:01 1997 @@ -325,6 +325,7 @@ extern const struct modem_rx_info sm_fsk9600_5_rx; extern const struct hardware_info sm_hw_sbc; +extern const struct hardware_info sm_hw_sbcfdx; extern const struct hardware_info sm_hw_wss; extern const struct hardware_info sm_hw_wssfdx; diff -u --recursive --new-file linux-2.1.30/drivers/net/soundmodem/sm_afsk1200.c linux/drivers/net/soundmodem/sm_afsk1200.c --- linux-2.1.30/drivers/net/soundmodem/sm_afsk1200.c Thu Mar 27 19:43:10 1997 +++ linux/drivers/net/soundmodem/sm_afsk1200.c Thu Mar 27 20:02:45 1997 @@ -1,7 +1,7 @@ /*****************************************************************************/ /* - * sm_afsk1200.h -- soundcard radio modem driver, 1200 baud AFSK modem + * sm_afsk1200.c -- soundcard radio modem driver, 1200 baud AFSK modem * * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch) * diff -u --recursive --new-file linux-2.1.30/drivers/net/soundmodem/sm_fsk9600.c linux/drivers/net/soundmodem/sm_fsk9600.c --- linux-2.1.30/drivers/net/soundmodem/sm_fsk9600.c Fri Mar 7 14:49:04 1997 +++ linux/drivers/net/soundmodem/sm_fsk9600.c Thu Mar 27 20:03:57 1997 @@ -1,7 +1,7 @@ /*****************************************************************************/ /* - * sm_fsk9600.h -- soundcard radio modem driver, + * sm_fsk9600.c -- soundcard radio modem driver, * 9600 baud G3RUH compatible FSK modem * * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch) diff -u --recursive --new-file linux-2.1.30/drivers/net/soundmodem/sm_hapn4800.c linux/drivers/net/soundmodem/sm_hapn4800.c --- linux-2.1.30/drivers/net/soundmodem/sm_hapn4800.c Fri Mar 7 14:49:05 1997 +++ linux/drivers/net/soundmodem/sm_hapn4800.c Thu Mar 27 20:03:40 1997 @@ -1,7 +1,7 @@ /*****************************************************************************/ /* - * sm_hapn4800.h -- soundcard radio modem driver, 4800 baud HAPN modem + * sm_hapn4800.c -- soundcard radio modem driver, 4800 baud HAPN modem * * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch) * diff -u --recursive --new-file linux-2.1.30/drivers/net/soundmodem/sm_sbc.c linux/drivers/net/soundmodem/sm_sbc.c --- linux-2.1.30/drivers/net/soundmodem/sm_sbc.c Thu Mar 27 19:43:10 1997 +++ linux/drivers/net/soundmodem/sm_sbc.c Wed Mar 26 15:08:54 1997 @@ -1,7 +1,7 @@ /*****************************************************************************/ /* - * sm_sbc.h -- soundcard radio modem driver soundblaster hardware driver + * sm_sbc.c -- soundcard radio modem driver soundblaster hardware driver * * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch) * @@ -80,9 +80,12 @@ struct sc_state_sbc { unsigned char revhi, revlo; unsigned char fmt[2]; + unsigned int sr[2]; unsigned int dmabuflen; unsigned char *dmabuf; + unsigned char *dmabuf2; unsigned char dmabufidx; + unsigned char dma2bufidx; unsigned char ptt; }; @@ -99,6 +102,7 @@ #define DSP_DATA_AVAIL(iobase) (iobase+0xe) #define DSP_MIXER_ADDR(iobase) (iobase+0x4) #define DSP_MIXER_DATA(iobase) (iobase+0x5) +#define DSP_INTACK_16BIT(iobase) (iobase+0xf) #define SBC_EXTENT 16 /* --------------------------------------------------------------------- */ @@ -122,6 +126,8 @@ #define SBC_DMA_ON 0xd0 #define SBC_DMA_OFF 0xd4 #define SBC_SAMPLE_RATE 0x40 +#define SBC_SAMPLE_RATE_OUT 0x41 +#define SBC_SAMPLE_RATE_IN 0x42 #define SBC_MONO_8BIT 0xa0 #define SBC_MONO_16BIT 0xa4 #define SBC_STEREO_8BIT 0xa8 @@ -131,6 +137,9 @@ #define SBC4_IN8_AI 0xce #define SBC4_MODE_UNS_MONO 0x00 +#define SBC4_OUT16_AI 0xb6 +#define SBC4_IN16_AI 0xbe + /* --------------------------------------------------------------------- */ static int inline reset_dsp(struct device *dev) @@ -179,13 +188,102 @@ /* --------------------------------------------------------------------- */ -static void inline sbc_int_ack(struct device *dev) +static int config_resources(struct device *dev, struct sm_state *sm, int fdx) +{ + unsigned char irqreg = 0, dmareg = 0, realirq, realdma; + unsigned long flags; + + switch (dev->irq) { + case 2: + case 9: + irqreg |= 0x01; + break; + + case 5: + irqreg |= 0x02; + break; + + case 7: + irqreg |= 0x04; + break; + + case 10: + irqreg |= 0x08; + break; + + default: + return -ENODEV; + } + + switch (dev->dma) { + case 0: + dmareg |= 0x01; + break; + + case 1: + dmareg |= 0x02; + break; + + case 3: + dmareg |= 0x08; + break; + + default: + return -ENODEV; + } + + if (fdx) { + switch (sm->hdrv.ptt_out.dma2) { + case 5: + dmareg |= 0x20; + break; + + case 6: + dmareg |= 0x40; + break; + + case 7: + dmareg |= 0x80; + break; + + default: + return -ENODEV; + } + } + save_flags(flags); + cli(); + outb(0x80, DSP_MIXER_ADDR(dev->base_addr)); + outb(irqreg, DSP_MIXER_DATA(dev->base_addr)); + realirq = inb(DSP_MIXER_DATA(dev->base_addr)); + outb(0x81, DSP_MIXER_ADDR(dev->base_addr)); + outb(dmareg, DSP_MIXER_DATA(dev->base_addr)); + realdma = inb(DSP_MIXER_DATA(dev->base_addr)); + restore_flags(flags); + if ((~realirq) & irqreg || (~realdma) & dmareg) { + printk(KERN_ERR "%s: sbc resource registers cannot be set; " + "PnP device and IRQ/DMA specified wrongly?\n", + sm_drvname); + return -EINVAL; + } + return 0; +} + +/* --------------------------------------------------------------------- */ + +static void inline sbc_int_ack_8bit(struct device *dev) { inb(DSP_DATA_AVAIL(dev->base_addr)); } /* --------------------------------------------------------------------- */ +static void inline sbc_int_ack_16bit(struct device *dev) +{ + inb(DSP_INTACK_16BIT(dev->base_addr)); +} + +/* --------------------------------------------------------------------- */ + static void setup_dma_dsp(struct device *dev, struct sm_state *sm, int send) { unsigned long flags; @@ -209,7 +307,7 @@ panic("sm: DMA buffer violates DMA boundary!"); save_flags(flags); cli(); - sbc_int_ack(dev); + sbc_int_ack_8bit(dev); write_dsp(dev, SBC_SAMPLE_RATE); /* set sampling rate */ write_dsp(dev, SCSTATE->fmt[send]); write_dsp(dev, sbcskr[send]); @@ -219,7 +317,7 @@ set_dma_addr(dev->dma, dmabufaddr); set_dma_count(dev->dma, SCSTATE->dmabuflen); enable_dma(dev->dma); - sbc_int_ack(dev); + sbc_int_ack_8bit(dev); if (SCSTATE->revhi >= 4) { write_dsp(dev, sbc4mode[send]); write_dsp(dev, SBC4_MODE_UNS_MONO); @@ -247,7 +345,7 @@ if (!dev || !sm || sm->hdrv.magic != HDLCDRV_MAGIC) return; new_ptt = hdlcdrv_ptt(&sm->hdrv); - sbc_int_ack(dev); + sbc_int_ack_8bit(dev); buf = SCSTATE->dmabuf; if (SCSTATE->dmabufidx) buf += SCSTATE->dmabuflen/2; @@ -294,6 +392,8 @@ static int sbc_open(struct device *dev, struct sm_state *sm) { + int err; + if (sizeof(sm->m) < sizeof(struct sc_state_sbc)) { printk(KERN_ERR "sm sbc: sbc state too big: %d > %d\n", sizeof(struct sc_state_sbc), sizeof(sm->m)); @@ -327,6 +427,11 @@ dev->base_addr, SCSTATE->revhi, SCSTATE->revlo); return -ENODEV; } + if (SCSTATE->revhi >= 4 && + (err = config_resources(dev, sm, 0))) { + printk(KERN_ERR "%s: invalid IRQ and/or DMA specified\n", sm_drvname); + return err; + } /* * initialize some variables */ @@ -521,6 +626,282 @@ const struct hardware_info sm_hw_sbc = { "sbc", sizeof(struct sc_state_sbc), sbc_open, sbc_close, sbc_ioctl, sbc_sethw +}; + +/* --------------------------------------------------------------------- */ + +static void setup_dma_fdx_dsp(struct device *dev, struct sm_state *sm) +{ + unsigned long flags; + unsigned long dmabufaddr = virt_to_bus(SCSTATE->dmabuf); + unsigned long dmabuf2addr = virt_to_bus(SCSTATE->dmabuf2); + + if (!reset_dsp(dev)) { + printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", sm_drvname); + return; + } + if (((dmabufaddr & 0xffff) + SCSTATE->dmabuflen > 0x10000) || + ((dmabuf2addr & 0xffff) + 2*(SCSTATE->dmabuflen) > 0x10000)) + panic("sm: DMA buffer violates DMA boundary!"); + save_flags(flags); + cli(); + sbc_int_ack_8bit(dev); + sbc_int_ack_16bit(dev); + /* should eventually change to set rates individually by SBC_SAMPLE_RATE_{IN/OUT} */ + write_dsp(dev, SBC_SAMPLE_RATE); /* set sampling rate */ + write_dsp(dev, SCSTATE->fmt[0]); + write_dsp(dev, SBC_SPEAKER_ON); + /* + * DMA channel 1 (8bit) does input (capture), + * DMA channel 2 (16bit) does output (playback) + */ + disable_dma(dev->dma); + disable_dma(sm->hdrv.ptt_out.dma2); + clear_dma_ff(dev->dma); + set_dma_mode(dev->dma, DMA_MODE_READ | DMA_MODE_AUTOINIT); + set_dma_addr(dev->dma, dmabufaddr); + set_dma_count(dev->dma, SCSTATE->dmabuflen); + clear_dma_ff(sm->hdrv.ptt_out.dma2); + set_dma_mode(sm->hdrv.ptt_out.dma2, DMA_MODE_WRITE | DMA_MODE_AUTOINIT); + set_dma_addr(sm->hdrv.ptt_out.dma2, dmabuf2addr); + set_dma_count(sm->hdrv.ptt_out.dma2, SCSTATE->dmabuflen); + enable_dma(dev->dma); + enable_dma(sm->hdrv.ptt_out.dma2); + sbc_int_ack_8bit(dev); + sbc_int_ack_16bit(dev); + write_dsp(dev, SBC4_IN8_AI); + write_dsp(dev, SBC4_MODE_UNS_MONO); + write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff); + write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) >> 8); + write_dsp(dev, SBC4_OUT16_AI); + write_dsp(dev, SBC4_MODE_UNS_MONO); + write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff); + write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) >> 8); + restore_flags(flags); +} + +/* --------------------------------------------------------------------- */ + +static void sbcfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct device *dev = (struct device *)dev_id; + struct sm_state *sm = (struct sm_state *)dev->priv; + unsigned char *buf; + unsigned char *buf2; + unsigned char intsrc; + + if (!dev || !sm || sm->hdrv.magic != HDLCDRV_MAGIC) + return; + buf = SCSTATE->dmabuf; + buf2 = SCSTATE->dmabuf2; + outb(0x82, DSP_MIXER_ADDR(dev->base_addr)); + intsrc = inb(DSP_MIXER_DATA(dev->base_addr)); + if (intsrc & 0x01) { + sbc_int_ack_8bit(dev); + if (SCSTATE->dmabufidx) + buf += SCSTATE->dmabuflen/2; + SCSTATE->dmabufidx = !SCSTATE->dmabufidx; + } + if (intsrc & 0x02) { + sbc_int_ack_16bit(dev); + if (SCSTATE->dma2bufidx) + buf2 += SCSTATE->dmabuflen/2; + SCSTATE->dma2bufidx = !SCSTATE->dma2bufidx; + } + sm_int_freq(sm); + sti(); + if (intsrc & 0x02) { + if ((SCSTATE->ptt = hdlcdrv_ptt(&sm->hdrv))) + time_exec(sm->debug_vals.mod_cyc, + sm->mode_tx->modulator(sm, buf2, SCSTATE->dmabuflen/2)); + else + time_exec(sm->debug_vals.mod_cyc, + memset(buf2, 0x80, SCSTATE->dmabuflen/2)); + } + if (intsrc & 0x01) { + time_exec(sm->debug_vals.demod_cyc, + sm->mode_rx->demodulator(sm, buf, SCSTATE->dmabuflen/2)); + hdlcdrv_arbitrate(dev, &sm->hdrv); + } + sm_output_status(sm); + hdlcdrv_transmitter(dev, &sm->hdrv); + hdlcdrv_receiver(dev, &sm->hdrv); +} + +/* --------------------------------------------------------------------- */ + +static int sbcfdx_open(struct device *dev, struct sm_state *sm) +{ + int err; + + if (sizeof(sm->m) < sizeof(struct sc_state_sbc)) { + printk(KERN_ERR "sm sbc: sbc state too big: %d > %d\n", + sizeof(struct sc_state_sbc), sizeof(sm->m)); + return -ENODEV; + } + if (!dev || !sm) + return -ENXIO; + if (dev->base_addr <= 0 || dev->base_addr > 0x1000-SBC_EXTENT || + dev->irq < 2 || dev->irq > 15 || dev->dma > 3) + return -ENXIO; + if (check_region(dev->base_addr, SBC_EXTENT)) + return -EACCES; + /* + * check if a card is available + */ + if (!reset_dsp(dev)) + return -ENODEV; + write_dsp(dev, SBC_GET_REVISION); + if (!read_dsp(dev, &SCSTATE->revhi) || + !read_dsp(dev, &SCSTATE->revlo)) + return -ENODEV; + if (SCSTATE->revhi < 4) { + printk(KERN_ERR "%s: at least DSP rev 4.00 required\n", sm_drvname); + return -ENODEV; + } + if ((err = config_resources(dev, sm, 1))) { + printk(KERN_ERR "%s: invalid IRQ and/or DMA specified\n", sm_drvname); + return err; + } + /* + * initialize some variables + */ + if (!(SCSTATE->dmabuf = kmalloc(SCSTATE->dmabuflen, GFP_KERNEL | GFP_DMA))) + return -ENOMEM; + if (!(SCSTATE->dmabuf2 = kmalloc(SCSTATE->dmabuflen, GFP_KERNEL | GFP_DMA))) { + kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen); + return -ENOMEM; + } + SCSTATE->dmabufidx = SCSTATE->dma2bufidx = SCSTATE->ptt = 0; + + memset(&sm->m, 0, sizeof(sm->m)); + memset(&sm->d, 0, sizeof(sm->d)); + if (sm->mode_tx->init) + sm->mode_tx->init(sm); + if (sm->mode_rx->init) + sm->mode_rx->init(sm); + + if (request_dma(dev->dma, sm->hwdrv->hw_name)) { + kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen); + kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen); + return -EBUSY; + } + if (request_dma(sm->hdrv.ptt_out.dma2, sm->hwdrv->hw_name)) { + kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen); + kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen); + free_dma(dev->dma); + return -EBUSY; + } + if (request_irq(dev->irq, sbcfdx_interrupt, SA_INTERRUPT, + sm->hwdrv->hw_name, dev)) { + kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen); + kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen); + free_dma(dev->dma); + free_dma(sm->hdrv.ptt_out.dma2); + return -EBUSY; + } + request_region(dev->base_addr, SBC_EXTENT, sm->hwdrv->hw_name); + setup_dma_fdx_dsp(dev, sm); + return 0; +} + +/* --------------------------------------------------------------------- */ + +static int sbcfdx_close(struct device *dev, struct sm_state *sm) +{ + if (!dev || !sm) + return -EINVAL; + /* + * disable interrupts + */ + disable_dma(dev->dma); + disable_dma(sm->hdrv.ptt_out.dma2); + reset_dsp(dev); + free_irq(dev->irq, dev); + free_dma(dev->dma); + free_dma(sm->hdrv.ptt_out.dma2); + release_region(dev->base_addr, SBC_EXTENT); + kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen); + kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen); + return 0; +} + +/* --------------------------------------------------------------------- */ + +static int sbcfdx_sethw(struct device *dev, struct sm_state *sm, char *mode) +{ + char *cp = strchr(mode, '.'); + const struct modem_tx_info **mtp = sm_modem_tx_table; + const struct modem_rx_info **mrp; + int dv; + + if (!strcmp(mode, "off")) { + sm->mode_tx = NULL; + sm->mode_rx = NULL; + return 0; + } + if (cp) + *cp++ = '\0'; + else + cp = mode; + for (; *mtp; mtp++) { + if ((*mtp)->loc_storage > sizeof(sm->m)) { + printk(KERN_ERR "%s: insufficient storage for modulator %s (%d)\n", + sm_drvname, (*mtp)->name, (*mtp)->loc_storage); + continue; + } + if (!(*mtp)->name || strcmp((*mtp)->name, mode)) + continue; + if ((*mtp)->srate < 5000 || (*mtp)->srate > 44100) + continue; + for (mrp = sm_modem_rx_table; *mrp; mrp++) { + if ((*mrp)->loc_storage > sizeof(sm->d)) { + printk(KERN_ERR "%s: insufficient storage for demodulator %s (%d)\n", + sm_drvname, (*mrp)->name, (*mrp)->loc_storage); + continue; + } + if ((*mrp)->name && !strcmp((*mrp)->name, cp) && + (*mtp)->srate >= 5000 && (*mtp)->srate <= 44100 && + (*mrp)->srate == (*mtp)->srate) { + sm->mode_tx = *mtp; + sm->mode_rx = *mrp; + SCSTATE->sr[0] = sm->mode_rx->srate; + SCSTATE->sr[1] = sm->mode_tx->srate; + dv = lcm(sm->mode_tx->dmabuflenmodulo, + sm->mode_rx->dmabuflenmodulo); + if (dv & 1) + dv <<= 1; /* dmabuflen must be a multiple of 4 */ + SCSTATE->dmabuflen = sm->mode_rx->srate/100+dv-1; + SCSTATE->dmabuflen /= dv; + SCSTATE->dmabuflen *= 2*dv; /* make sure DMA buf is even */ + return 0; + } + } + } + return -EINVAL; +} + +/* --------------------------------------------------------------------- */ + +static int sbcfdx_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr, + struct hdlcdrv_ioctl *hi, int cmd) +{ + if (cmd != SIOCDEVPRIVATE) + return -ENOIOCTLCMD; + + if (hi->cmd == HDLCDRVCTL_MODEMPARMASK) + return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ | + HDLCDRV_PARMASK_DMA | HDLCDRV_PARMASK_DMA2 | HDLCDRV_PARMASK_SERIOBASE | + HDLCDRV_PARMASK_PARIOBASE | HDLCDRV_PARMASK_MIDIIOBASE; + + return sbc_ioctl(dev, sm, ifr, hi, cmd); +} + +/* --------------------------------------------------------------------- */ + +const struct hardware_info sm_hw_sbcfdx = { + "sbcfdx", sizeof(struct sc_state_sbc), + sbcfdx_open, sbcfdx_close, sbcfdx_ioctl, sbcfdx_sethw }; /* --------------------------------------------------------------------- */ diff -u --recursive --new-file linux-2.1.30/include/linux/ax25.h linux/include/linux/ax25.h --- linux-2.1.30/include/linux/ax25.h Fri Mar 7 14:49:07 1997 +++ linux/include/linux/ax25.h Tue Mar 25 09:55:42 1997 @@ -16,7 +16,7 @@ #define AX25_T2 5 #define AX25_BACKOFF 6 #define AX25_EXTSEQ 7 -#define AX25_HDRINCL 8 +#define AX25_PIDINCL 8 #define AX25_IDLE 9 #define AX25_PACLEN 10 #define AX25_IAMDIGI 12 diff -u --recursive --new-file linux-2.1.30/include/linux/netrom.h linux/include/linux/netrom.h --- linux-2.1.30/include/linux/netrom.h Fri Mar 7 14:49:08 1997 +++ linux/include/linux/netrom.h Tue Mar 25 09:55:48 1997 @@ -13,7 +13,6 @@ #define NETROM_T1 1 #define NETROM_T2 2 #define NETROM_N2 3 -#define NETROM_HDRINCL 4 #define NETROM_T4 6 #define NETROM_IDLE 7 diff -u --recursive --new-file linux-2.1.30/include/linux/proc_fs.h linux/include/linux/proc_fs.h --- linux-2.1.30/include/linux/proc_fs.h Thu Mar 27 19:43:21 1997 +++ linux/include/linux/proc_fs.h Thu Mar 27 21:29:54 1997 @@ -129,7 +129,6 @@ PROC_NET_RS_ROUTES, PROC_NET_RS, PROC_NET_CL2LLC, - PROC_NET_X25_LINKS, PROC_NET_X25_ROUTES, PROC_NET_X25, PROC_NET_TR_RIF, diff -u --recursive --new-file linux-2.1.30/include/linux/rose.h linux/include/linux/rose.h --- linux-2.1.30/include/linux/rose.h Fri Mar 7 14:48:14 1997 +++ linux/include/linux/rose.h Tue Mar 25 09:55:57 1997 @@ -14,7 +14,7 @@ #define ROSE_T2 3 #define ROSE_T3 4 #define ROSE_IDLE 5 -#define ROSE_HDRINCL 6 +#define ROSE_QBITINCL 6 #define ROSE_HOLDBACK 7 #define ROSE_KILL 99 diff -u --recursive --new-file linux-2.1.30/include/net/ax25.h linux/include/net/ax25.h --- linux-2.1.30/include/net/ax25.h Thu Mar 27 19:43:22 1997 +++ linux/include/net/ax25.h Thu Mar 27 21:29:21 1997 @@ -46,32 +46,12 @@ #define AX25_COND_REJECT 0x02 #define AX25_COND_PEER_RX_BUSY 0x04 #define AX25_COND_OWN_RX_BUSY 0x08 +#define AX25_COND_DAMA_MODE 0x10 #ifndef _LINUX_NETDEVICE_H #include #endif -/* - * These headers are taken from the KA9Q package by Phil Karn. These specific - * files have been placed under the GPL (not the whole package) by Phil. - * - * - * Copyright 1991 Phil Karn, KA9Q - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 dated June, 1991. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA. - */ - /* Upper sub-layer (LAPB) definitions */ /* Control field templates */ @@ -149,7 +129,7 @@ #define AX25_DEF_T2 (3 * AX25_SLOWHZ) /* T2=3s */ #define AX25_DEF_T3 (300 * AX25_SLOWHZ) /* T3=300s */ #define AX25_DEF_N2 10 /* N2=10 */ -#define AX25_DEF_IDLE (20 * 60 * AX25_SLOWHZ) /* Idle=20 mins */ +#define AX25_DEF_IDLE (0 * 60 * AX25_SLOWHZ) /* Idle=None */ #define AX25_DEF_PACLEN 256 /* Paclen=256 */ #define AX25_DEF_PROTOCOL AX25_PROTO_STD_SIMPLEX /* Standard AX.25 */ #define AX25_DEF_DS_TIMEOUT (3 * 60 * AX25_SLOWHZ) /* DAMA timeout 3 minutes */ @@ -202,17 +182,13 @@ ax25_digi *digipeat; ax25_dev *ax25_dev; unsigned char iamdigi; - unsigned char state, modulus, hdrincl; + unsigned char state, modulus, pidincl; unsigned short vs, vr, va; unsigned char condition, backoff; unsigned char n2, n2count; -#ifdef CONFIG_AX25_DAMA_SLAVE - unsigned char dama_slave; -#endif unsigned short t1, t2, t3, idle, rtt; unsigned short t1timer, t2timer, t3timer, idletimer; - unsigned short paclen; - unsigned short fragno, fraglen; + unsigned short paclen, fragno, fraglen; struct sk_buff_head write_queue; struct sk_buff_head reseq_queue; struct sk_buff_head ack_queue; @@ -313,7 +289,7 @@ extern int ax25_rt_get_info(char *, char **, off_t, int, int); extern int ax25_rt_autobind(ax25_cb *, ax25_address *); extern void ax25_rt_build_path(ax25_cb *, ax25_address *, struct device *); -extern void ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *); +extern struct sk_buff *ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *); extern char ax25_ip_mode_get(ax25_address *, struct device *); extern void ax25_rt_free(void); diff -u --recursive --new-file linux-2.1.30/include/net/netrom.h linux/include/net/netrom.h --- linux-2.1.30/include/net/netrom.h Fri Mar 7 14:49:10 1997 +++ linux/include/net/netrom.h Tue Mar 25 09:56:27 1997 @@ -61,7 +61,7 @@ struct device *device; unsigned char my_index, my_id; unsigned char your_index, your_id; - unsigned char state, condition, bpqext, hdrincl, window; + unsigned char state, condition, bpqext, window; unsigned short vs, vr, va, vl; unsigned char n2, n2count; unsigned short t1, t2, t4, idle; diff -u --recursive --new-file linux-2.1.30/include/net/rose.h linux/include/net/rose.h --- linux-2.1.30/include/net/rose.h Fri Mar 7 14:49:10 1997 +++ linux/include/net/rose.h Tue Mar 25 09:56:35 1997 @@ -77,31 +77,41 @@ #define FAC_CCITT_SRC_NSAP 0xCB struct rose_neigh { - struct rose_neigh *next; - ax25_address callsign; - ax25_digi *digipeat; - struct device *dev; - unsigned short count; - unsigned int number; - int restarted; - struct sk_buff_head queue; - unsigned short t0timer, ftimer; - struct timer_list timer; + struct rose_neigh *next; + ax25_address callsign; + ax25_digi *digipeat; + struct device *dev; + unsigned short count; + unsigned int number; + int restarted; + struct sk_buff_head queue; + unsigned short t0timer, ftimer; + struct timer_list timer; }; struct rose_node { - struct rose_node *next; - rose_address address; - unsigned short mask; - unsigned char count; - struct rose_neigh *neighbour[3]; + struct rose_node *next; + rose_address address; + unsigned short mask; + unsigned char count; + struct rose_neigh *neighbour[3]; }; struct rose_route { - struct rose_route *next; - unsigned int lci1, lci2; - struct rose_neigh *neigh1, *neigh2; - unsigned int rand; + struct rose_route *next; + unsigned int lci1, lci2; + rose_address src_addr, dest_addr; + ax25_address src_call, dest_call; + struct rose_neigh *neigh1, *neigh2; + unsigned int rand; +}; + +struct rose_facilities { + rose_address source_addr, dest_addr; + ax25_address source_call, dest_call; + unsigned char source_ndigis, dest_ndigis; + ax25_address source_digi, dest_digi; + unsigned int rand; }; typedef struct { @@ -112,7 +122,7 @@ struct rose_neigh *neighbour; struct device *device; unsigned int lci, rand; - unsigned char state, condition, hdrincl; + unsigned char state, condition, qbitincl; unsigned short vs, vr, va, vl; unsigned short timer; unsigned short t1, t2, t3, hb, idle; @@ -135,6 +145,7 @@ extern int rosecmpm(rose_address *, rose_address *, unsigned short); extern char *rose2asc(rose_address *); extern struct sock *rose_find_socket(unsigned int, struct device *); +extern void rose_kill_by_neigh(struct rose_neigh *); extern unsigned int rose_new_lci(struct device *); extern int rose_rx_call_request(struct sk_buff *, struct device *, struct rose_neigh *, unsigned int); extern void rose_destroy_socket(struct sock *); @@ -183,7 +194,7 @@ extern int rose_validate_nr(struct sock *, unsigned short); extern void rose_write_internal(struct sock *, int); extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *); -extern int rose_parse_facilities(struct sk_buff *, rose_cb *); +extern int rose_parse_facilities(struct sk_buff *, struct rose_facilities *); extern int rose_create_facilities(unsigned char *, rose_cb *); /* rose_timer.c */ diff -u --recursive --new-file linux-2.1.30/include/net/sock.h linux/include/net/sock.h --- linux-2.1.30/include/net/sock.h Thu Mar 27 19:43:23 1997 +++ linux/include/net/sock.h Fri Mar 28 13:51:37 1997 @@ -271,20 +271,23 @@ * sockmem [mem, proto, callbacks] * * union or struct { - * netrom; - * ax_25; + * ax25; * } ll_pinfo; * * union { * ipv4; * ipv6; * ipx; + * netrom; + * rose; + * x25; * } net_pinfo; * * union { * tcp; * udp; * spx; + * netrom; * } tp_pinfo; * * } diff -u --recursive --new-file linux-2.1.30/include/net/x25.h linux/include/net/x25.h --- linux-2.1.30/include/net/x25.h Fri Mar 7 14:49:10 1997 +++ linux/include/net/x25.h Tue Mar 11 17:37:49 1997 @@ -157,6 +157,11 @@ extern void x25_establish_link(struct x25_neigh *); extern void x25_terminate_link(struct x25_neigh *); +/* x25_facilities.c */ +extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *); +extern int x25_create_facilities(unsigned char *, struct x25_facilities *); +extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *); + /* x25_in.c */ extern int x25_process_rx_frame(struct sock *, struct sk_buff *); @@ -173,7 +178,6 @@ extern void x25_transmit_link(struct sk_buff *, struct x25_neigh *); extern int x25_subscr_ioctl(unsigned int, void *); extern struct x25_neigh *x25_get_neigh(struct device *); -extern int x25_link_get_info(char *, char **, off_t, int, int); extern void x25_link_free(void); /* x25_out.c */ @@ -195,8 +199,6 @@ extern int x25_validate_nr(struct sock *, unsigned short); extern void x25_write_internal(struct sock *, int); extern int x25_decode(struct sock *, struct sk_buff *, int *, int *, int *, int *, int *); -extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *); -extern int x25_create_facilities(unsigned char *, struct x25_facilities *); /* x25_timer.c */ extern void x25_set_timer(struct sock *); diff -u --recursive --new-file linux-2.1.30/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c --- linux-2.1.30/net/ax25/af_ax25.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/af_ax25.c Thu Mar 27 21:40:46 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -140,11 +137,11 @@ void ax25_free_cb(ax25_cb *ax25) { if (ax25->digipeat != NULL) { - kfree_s(ax25->digipeat, sizeof(ax25_digi)); + kfree(ax25->digipeat); ax25->digipeat = NULL; } - kfree_s(ax25, sizeof(ax25_cb)); + kfree(ax25); MOD_DEC_USE_COUNT; } @@ -467,7 +464,6 @@ if (ax25_dev->dama.slave && ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_DAMA_SLAVE) ax25_dama_off(ax25); #endif - if (ax25->sk != NULL) { ax25->sk->state = TCP_CLOSE; ax25->sk->err = ENETRESET; @@ -476,9 +472,8 @@ ax25->sk->state_change(ax25->sk); ax25->sk->dead = 1; } - ax25_set_timer(ax25); - break; + break; case AX25_WINDOW: if (ax25->modulus == AX25_MODULUS) { @@ -693,8 +688,8 @@ sk->protinfo.ax25->modulus = opt ? AX25_EMODULUS : AX25_MODULUS; return 0; - case AX25_HDRINCL: - sk->protinfo.ax25->hdrincl = opt ? 1 : 0; + case AX25_PIDINCL: + sk->protinfo.ax25->pidincl = opt ? 1 : 0; return 0; case AX25_IAMDIGI: @@ -757,8 +752,8 @@ val = (sk->protinfo.ax25->modulus == AX25_EMODULUS); break; - case AX25_HDRINCL: - val = sk->protinfo.ax25->hdrincl; + case AX25_PIDINCL: + val = sk->protinfo.ax25->pidincl; break; case AX25_IAMDIGI: @@ -905,7 +900,7 @@ ax25->modulus = osk->protinfo.ax25->modulus; ax25->backoff = osk->protinfo.ax25->backoff; - ax25->hdrincl = osk->protinfo.ax25->hdrincl; + ax25->pidincl = osk->protinfo.ax25->pidincl; ax25->iamdigi = osk->protinfo.ax25->iamdigi; ax25->rtt = osk->protinfo.ax25->rtt; ax25->t1 = osk->protinfo.ax25->t1; @@ -1178,6 +1173,8 @@ #ifdef CONFIG_AX25_DAMA_SLAVE case AX25_PROTO_DAMA_SLAVE: + ax25->modulus = AX25_MODULUS; + ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW]; if (sk->protinfo.ax25->ax25_dev->dama.slave) ax25_ds_establish_data_link(sk->protinfo.ax25); else @@ -1401,9 +1398,11 @@ /* User data follows immediately after the AX.25 data */ memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); - /* Add the PID, usually AX25_TEXT */ - asmptr = skb_push(skb, 1); - *asmptr = sk->protocol; + /* Add the PID if one is not supplied by the user in the skb */ + if (!sk->protinfo.ax25->pidincl) { + asmptr = skb_push(skb, 1); + *asmptr = sk->protocol; + } SOCK_DEBUG(sk, "AX.25: Transmitting buffer\n"); @@ -1450,10 +1449,9 @@ { struct sock *sk = sock->sk; struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name; - int copied, length; + int copied; struct sk_buff *skb; int er; - int dama; /* * This works for seqpacket too. The receiver has ordered the @@ -1466,16 +1464,11 @@ if ((skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &er)) == NULL) return er; - if (sk->protinfo.ax25->hdrincl) { - length = skb->len + (skb->data - skb->h.raw); - } else { - if (sk->type == SOCK_SEQPACKET) - skb_pull(skb, 1); /* Remove PID */ - length = skb->len; - skb->h.raw = skb->data; - } + if (!sk->protinfo.ax25->pidincl) + skb_pull(skb, 1); /* Remove PID */ - copied = length; + skb->h.raw = skb->data; + copied = skb->len; if (copied > size) { copied = size; @@ -1487,6 +1480,7 @@ if (sax != NULL) { ax25_digi digi; ax25_address dest; + int dama; ax25_addr_parse(skb->data, skb->len, NULL, &dest, &digi, NULL, &dama); @@ -1809,6 +1803,9 @@ } #ifdef MODULE +MODULE_AUTHOR("Jonathan Naylor G4KLX "); +MODULE_DESCRIPTION("The amateur radio AX.25 link layer protocol"); + int init_module(void) { ax25_proto_init(NULL); diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_addr.c linux/net/ax25/ax25_addr.c --- linux-2.1.30/net/ax25/ax25_addr.c Fri Mar 7 14:49:12 1997 +++ linux/net/ax25/ax25_addr.c Sat Mar 15 20:12:00 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_dev.c linux/net/ax25/ax25_dev.c --- linux-2.1.30/net/ax25/ax25_dev.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/ax25_dev.c Thu Mar 27 20:23:32 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -77,7 +74,7 @@ unsigned long flags; if ((ax25_dev = kmalloc(sizeof(*ax25_dev), GFP_ATOMIC)) == NULL) { - printk(KERN_ERR "ax25_dev_device_up out of memory\n"); + printk(KERN_ERR "AX.25: ax25_dev_device_up - out of memory\n"); return; } @@ -100,11 +97,7 @@ ax25_dev->values[AX25_VALUES_IDLE] = AX25_DEF_IDLE; ax25_dev->values[AX25_VALUES_N2] = AX25_DEF_N2; ax25_dev->values[AX25_VALUES_PACLEN] = AX25_DEF_PACLEN; -#ifdef CONFIG_AX25_DAMA_SLAVE - ax25_dev->values[AX25_VALUES_PROTOCOL] = AX25_PROTO_DAMA_SLAVE; -#else ax25_dev->values[AX25_VALUES_PROTOCOL] = AX25_DEF_PROTOCOL; -#endif ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT; save_flags(flags); cli(); @@ -141,7 +134,7 @@ if ((s = ax25_dev_list) == ax25_dev) { ax25_dev_list = s->next; restore_flags(flags); - kfree_s(ax25_dev, sizeof(ax25_dev)); + kfree(ax25_dev); ax25_register_sysctl(); return; } @@ -150,7 +143,7 @@ if (s->next == ax25_dev) { s->next = ax25_dev->next; restore_flags(flags); - kfree_s(ax25_dev, sizeof(ax25_dev)); + kfree(ax25_dev); ax25_register_sysctl(); return; } @@ -217,7 +210,7 @@ s = ax25_dev; ax25_dev = ax25_dev->next; - kfree_s(s, sizeof(ax25_dev)); + kfree(s); } } diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_ds_in.c linux/net/ax25/ax25_ds_in.c --- linux-2.1.30/net/ax25/ax25_ds_in.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/ax25_ds_in.c Thu Mar 27 20:30:23 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -61,12 +58,6 @@ ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); break; - case AX25_SABME: - ax25->modulus = AX25_EMODULUS; - ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW]; - ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); - break; - case AX25_DISC: ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE); break; @@ -100,20 +91,15 @@ case AX25_DM: if (pf) { - if (ax25->modulus == AX25_MODULUS) { - ax25_clear_queues(ax25); - ax25->state = AX25_STATE_0; - if (ax25->sk != NULL) { - ax25->sk->state = TCP_CLOSE; - ax25->sk->err = ECONNREFUSED; - ax25->sk->shutdown |= SEND_SHUTDOWN; - if (!ax25->sk->dead) - ax25->sk->state_change(ax25->sk); - ax25->sk->dead = 1; - } - } else { - ax25->modulus = AX25_MODULUS; - ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW]; + ax25_clear_queues(ax25); + ax25->state = AX25_STATE_0; + if (ax25->sk != NULL) { + ax25->sk->state = TCP_CLOSE; + ax25->sk->err = ECONNREFUSED; + ax25->sk->shutdown |= SEND_SHUTDOWN; + if (!ax25->sk->dead) + ax25->sk->state_change(ax25->sk); + ax25->sk->dead = 1; } } break; @@ -136,9 +122,7 @@ { switch (frametype) { case AX25_SABM: - case AX25_SABME: ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); - ax25->dama_slave = 0; ax25_dama_off(ax25); break; @@ -146,7 +130,6 @@ ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); ax25->state = AX25_STATE_0; ax25_dama_off(ax25); - if (ax25->sk != NULL) { ax25->sk->state = TCP_CLOSE; ax25->sk->err = 0; @@ -162,7 +145,6 @@ if (pf) { ax25->state = AX25_STATE_0; ax25_dama_off(ax25); - if (ax25->sk != NULL) { ax25->sk->state = TCP_CLOSE; ax25->sk->err = 0; @@ -180,7 +162,6 @@ case AX25_RR: if (pf) { ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); - ax25->dama_slave = 0; ax25_dama_off(ax25); } break; @@ -203,14 +184,8 @@ switch (frametype) { case AX25_SABM: - case AX25_SABME: - if (frametype == AX25_SABM) { - ax25->modulus = AX25_MODULUS; - ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW]; - } else { - ax25->modulus = AX25_EMODULUS; - ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW]; - } + ax25->modulus = AX25_MODULUS; + ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW]; ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); ax25->condition = 0x00; ax25->t1timer = 0; @@ -229,7 +204,6 @@ ax25->t3timer = 0; ax25->state = AX25_STATE_0; ax25_dama_off(ax25); - if (ax25->sk != NULL) { ax25->sk->state = TCP_CLOSE; ax25->sk->err = 0; @@ -245,7 +219,6 @@ ax25->t3timer = 0; ax25->state = AX25_STATE_0; ax25_dama_off(ax25); - if (ax25->sk != NULL) { ax25->sk->state = TCP_CLOSE; ax25->sk->err = ECONNRESET; @@ -306,193 +279,7 @@ break; } if (ns == ax25->vr) { - ax25->vr = (ax25->vr + 1) % ax25->modulus; - queued = ax25_rx_iframe(ax25, skb); - if (ax25->condition & AX25_COND_OWN_RX_BUSY) { - ax25->vr = ns; /* ax25->vr - 1 */ - if (pf) ax25_ds_enquiry_response(ax25); - break; - } - ax25->condition &= ~AX25_COND_REJECT; - if (pf) { - ax25_ds_enquiry_response(ax25); - } else { - if (!(ax25->condition & AX25_COND_ACK_PENDING)) { - ax25->t2timer = ax25->t2; - ax25->condition |= AX25_COND_ACK_PENDING; - } - } - } else { - if (ax25->condition & AX25_COND_REJECT) { - if (pf) ax25_ds_enquiry_response(ax25); - } else { - ax25->condition |= AX25_COND_REJECT; - ax25_ds_enquiry_response(ax25); - ax25->condition &= ~AX25_COND_ACK_PENDING; - } - } - break; - - case AX25_FRMR: - case AX25_ILLEGAL: - ax25_ds_establish_data_link(ax25); - ax25->state = AX25_STATE_1; - break; - - default: - break; - } - - return queued; -} - -/* - * State machine for state 4, Timer Recovery State. - * The handling of the timer(s) is in file ax25_timer.c - * Handling of state 0 and connection release is in ax25.c. - */ -static int ax25_ds_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type) -{ - int queued = 0; - - switch (frametype) { - case AX25_SABM: - case AX25_SABME: - if (frametype == AX25_SABM) { - ax25->modulus = AX25_MODULUS; - ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW]; - } else { - ax25->modulus = AX25_EMODULUS; - ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW]; - } - ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); - ax25->condition = 0x00; - ax25->t1timer = 0; - ax25->t3timer = ax25->t3; - ax25->idletimer = ax25->idle; - ax25->vs = 0; - ax25->va = 0; - ax25->vr = 0; - ax25->state = AX25_STATE_3; - ax25->n2count = 0; - ax25_requeue_frames(ax25); - ax25_dama_on(ax25); - break; - - case AX25_DISC: - ax25_clear_queues(ax25); - ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); - ax25->t3timer = 0; - ax25->state = AX25_STATE_0; - ax25_dama_off(ax25); - - if (ax25->sk != NULL) { - ax25->sk->state = TCP_CLOSE; - ax25->sk->err = 0; - ax25->sk->shutdown |= SEND_SHUTDOWN; - if (!ax25->sk->dead) - ax25->sk->state_change(ax25->sk); - ax25->sk->dead = 1; - } - break; - - case AX25_DM: - ax25_clear_queues(ax25); - ax25->t3timer = 0; - ax25->state = AX25_STATE_0; - ax25_dama_off(ax25); - - if (ax25->sk != NULL) { - ax25->sk->state = TCP_CLOSE; - ax25->sk->err = ECONNRESET; - ax25->sk->shutdown |= SEND_SHUTDOWN; - if (!ax25->sk->dead) - ax25->sk->state_change(ax25->sk); - ax25->sk->dead = 1; - } - break; - - case AX25_RR: - case AX25_RNR: - if (frametype == AX25_RR) - ax25->condition &= ~AX25_COND_PEER_RX_BUSY; - else - ax25->condition |= AX25_COND_PEER_RX_BUSY; - if (type == AX25_RESPONSE && pf) { - ax25->t1timer = 0; - if (ax25_validate_nr(ax25, nr)) { - ax25_frames_acked(ax25, nr); - ax25->n2count = 0; - if (ax25->vs == ax25->va) { - ax25->t3timer = ax25->t3; - ax25->state = AX25_STATE_3; - } else { - ax25_requeue_frames(ax25); - } - } else { - ax25_ds_nr_error_recovery(ax25); - ax25->state = AX25_STATE_1; - } - break; - } - if (ax25_validate_nr(ax25, nr)) { - ax25_frames_acked(ax25, nr); - ax25->n2count = 0; - if (type == AX25_COMMAND && pf) - ax25_ds_enquiry_response(ax25); - } else { - ax25_ds_nr_error_recovery(ax25); - ax25->state = AX25_STATE_1; - } - break; - - case AX25_REJ: - ax25->condition &= ~AX25_COND_PEER_RX_BUSY; - if (pf) { - ax25->t1timer = 0; - if (ax25_validate_nr(ax25, nr)) { - ax25_frames_acked(ax25, nr); - ax25->n2count = 0; - if (ax25->vs == ax25->va) { - ax25->t3timer = ax25->t3; - ax25->state = AX25_STATE_3; - } else { - ax25_requeue_frames(ax25); - } - if (type == AX25_COMMAND && pf) - ax25_ds_enquiry_response(ax25); - } else { - ax25_ds_nr_error_recovery(ax25); - ax25->state = AX25_STATE_1; - } - break; - } - if (ax25_validate_nr(ax25, nr)) { - ax25_frames_acked(ax25, nr); - ax25->n2count = 0; - ax25_requeue_frames(ax25); - if (type == AX25_COMMAND && pf) - ax25_ds_enquiry_response(ax25); - } else { - ax25_ds_nr_error_recovery(ax25); - ax25->state = AX25_STATE_1; - } - break; - - case AX25_I: - if (!ax25_validate_nr(ax25, nr)) { - ax25_ds_nr_error_recovery(ax25); - ax25->state = AX25_STATE_1; - break; - } - ax25_frames_acked(ax25, nr); - ax25->n2count = 0; - if (ax25->condition & AX25_COND_OWN_RX_BUSY) { - if (pf) ax25_ds_enquiry_response(ax25); - break; - } - if (ns == ax25->vr) { - ax25->vr = (ax25->vr + 1) % ax25->modulus; + ax25->vr = (ax25->vr + 1) % AX25_MODULUS; queued = ax25_rx_iframe(ax25, skb); if (ax25->condition & AX25_COND_OWN_RX_BUSY) { ax25->vr = ns; /* ax25->vr - 1 */ @@ -550,9 +337,6 @@ break; case AX25_STATE_3: queued = ax25_ds_state3_machine(ax25, skb, frametype, ns, nr, pf, type); - break; - case AX25_STATE_4: - queued = ax25_ds_state4_machine(ax25, skb, frametype, ns, nr, pf, type); break; } diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_ds_subr.c linux/net/ax25/ax25_ds_subr.c --- linux-2.1.30/net/ax25/ax25_ds_subr.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/ax25_ds_subr.c Thu Mar 27 20:30:46 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -109,9 +106,7 @@ continue; } - if (!(ax25o->condition & AX25_COND_PEER_RX_BUSY) && - (ax25o->state == AX25_STATE_3 || - (ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0))) { + if (!(ax25o->condition & AX25_COND_PEER_RX_BUSY) && ax25o->state == AX25_STATE_3) { ax25_requeue_frames(ax25o); ax25_kick(ax25o); } @@ -125,12 +120,11 @@ void ax25_ds_establish_data_link(ax25_cb *ax25) { - ax25->condition = 0x00; - ax25->n2count = 0; - - ax25->t3timer = ax25->t3; - ax25->t2timer = 0; - ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25); + ax25->condition &= AX25_COND_DAMA_MODE; + ax25->n2count = 0; + ax25->t3timer = ax25->t3; + ax25->t2timer = 0; + ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25); } /* @@ -139,7 +133,6 @@ * We need a driver level request to switch duplex mode, that does * either SCC changing, PI config or KISS as required. Currently * this request isn't reliable. - * */ static void ax25_kiss_cmd(ax25_dev *ax25_dev, unsigned char cmd, unsigned char param) { @@ -173,13 +166,12 @@ * ax25->dama_slave=1 and look on every disconnect if still slave * connections exist. */ - static int ax25_check_dama_slave(ax25_dev *ax25_dev) { ax25_cb *ax25; for (ax25 = ax25_list; ax25 != NULL ; ax25 = ax25->next) - if (ax25->ax25_dev == ax25_dev && ax25->dama_slave && ax25->state > AX25_STATE_1) + if (ax25->ax25_dev == ax25_dev && (ax25->condition & AX25_COND_DAMA_MODE) && ax25->state > AX25_STATE_1) return 1; return 0; @@ -202,8 +194,7 @@ if (ax25_dev == NULL) return; - if (ax25_dev->dama.slave && !ax25_check_dama_slave(ax25_dev)) - { + if (ax25_dev->dama.slave && !ax25_check_dama_slave(ax25_dev)) { ax25_kiss_cmd(ax25_dev, 5, 0); ax25_dev->dama.slave = 0; ax25_ds_del_timer(ax25_dev); @@ -213,13 +204,13 @@ void ax25_dama_on(ax25_cb *ax25) { ax25_dev_dama_on(ax25->ax25_dev); - ax25->dama_slave = 1; + ax25->condition |= AX25_COND_DAMA_MODE; } void ax25_dama_off(ax25_cb *ax25) { ax25_dev_dama_off(ax25->ax25_dev); - ax25->dama_slave = 0; + ax25->condition &= ~AX25_COND_DAMA_MODE; } #endif diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_ds_timer.c linux/net/ax25/ax25_ds_timer.c --- linux-2.1.30/net/ax25/ax25_ds_timer.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/ax25_ds_timer.c Thu Mar 27 20:31:06 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -87,15 +84,13 @@ if (ax25_dev == NULL || !ax25_dev->dama.slave) return; /* Yikes! */ - if (!ax25_dev->dama.slave_timeout || --ax25_dev->dama.slave_timeout) - { + if (!ax25_dev->dama.slave_timeout || --ax25_dev->dama.slave_timeout) { ax25_ds_set_timer(ax25_dev); return; } - for (ax25=ax25_list; ax25 != NULL; ax25 = ax25->next) - { - if (ax25->ax25_dev != ax25_dev || !ax25->dama_slave) + for (ax25=ax25_list; ax25 != NULL; ax25 = ax25->next) { + if (ax25->ax25_dev != ax25_dev || !(ax25->condition & AX25_COND_DAMA_MODE)) continue; ax25_link_failed(&ax25->dest_addr, ax25_dev->dev); @@ -103,8 +98,7 @@ ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); ax25->state = AX25_STATE_0; - if (ax25->sk != NULL) - { + if (ax25->sk != NULL) { SOCK_DEBUG(ax25->sk, "AX.25 DAMA Slave Timeout\n"); ax25->sk->state = TCP_CLOSE; ax25->sk->err = ETIMEDOUT; @@ -120,7 +114,6 @@ ax25_dev_dama_off(ax25_dev); } - /* * AX.25 TIMER * @@ -141,7 +134,6 @@ break; case AX25_STATE_3: - case AX25_STATE_4: /* * Check the state of the receive buffer. */ @@ -279,12 +271,7 @@ } break; - case AX25_STATE_3: - ax25->n2count = 1; - ax25->state = AX25_STATE_4; - break; - - case AX25_STATE_4: + case AX25_STATE_3: if (ax25->n2count == ax25->n2) { ax25_link_failed(&ax25->dest_addr, ax25->ax25_dev->dev); ax25_clear_queues(ax25); diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_iface.c linux/net/ax25/ax25_iface.c --- linux-2.1.30/net/ax25/ax25_iface.c Fri Mar 7 14:49:12 1997 +++ linux/net/ax25/ax25_iface.c Sun Mar 16 11:08:32 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -98,7 +95,7 @@ if (protocol->pid == pid) { protocol_list = protocol->next; restore_flags(flags); - kfree_s(protocol, sizeof(struct protocol_struct)); + kfree(protocol); return; } @@ -107,7 +104,7 @@ s = protocol->next; protocol->next = protocol->next->next; restore_flags(flags); - kfree_s(s, sizeof(struct protocol_struct)); + kfree(s); return; } @@ -152,7 +149,7 @@ if (linkfail->func == func) { linkfail_list = linkfail->next; restore_flags(flags); - kfree_s(linkfail, sizeof(struct linkfail_struct)); + kfree(linkfail); return; } @@ -161,7 +158,7 @@ s = linkfail->next; linkfail->next = linkfail->next->next; restore_flags(flags); - kfree_s(s, sizeof(struct linkfail_struct)); + kfree(s); return; } @@ -210,7 +207,7 @@ if (ax25cmp(&listen->callsign, callsign) == 0 && listen->dev == dev) { listen_list = listen->next; restore_flags(flags); - kfree_s(listen, sizeof(struct listen_struct)); + kfree(listen); return; } @@ -219,7 +216,7 @@ s = listen->next; listen->next = listen->next->next; restore_flags(flags); - kfree_s(s, sizeof(struct listen_struct)); + kfree(s); return; } diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_in.c linux/net/ax25/ax25_in.c --- linux-2.1.30/net/ax25/ax25_in.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/ax25_in.c Thu Mar 27 20:25:55 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -73,7 +70,6 @@ static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb) { struct sk_buff *skbn, *skbo; - int hdrlen, nhdrlen; if (ax25->fragno != 0) { if (!(*skb->data & AX25_SEG_FIRST)) { @@ -86,35 +82,20 @@ /* Last fragment received ? */ if (ax25->fragno == 0) { - if ((skbn = alloc_skb(AX25_MAX_HEADER_LEN + ax25->fraglen, GFP_ATOMIC)) == NULL) { + if ((skbn = alloc_skb(ax25->fraglen, GFP_ATOMIC)) == NULL) { while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) kfree_skb(skbo, FREE_READ); return 1; } - skbn->dev = ax25->ax25_dev->dev; - - skb_reserve(skbn, AX25_MAX_HEADER_LEN); - - /* Get first fragment from queue */ - skbo = skb_dequeue(&ax25->frag_queue); - hdrlen = skbo->data - skbo->h.raw; - nhdrlen = hdrlen - 2; - - skb_push(skbo, hdrlen); - skb_push(skbn, nhdrlen); + skbn->dev = ax25->ax25_dev->dev; skbn->h.raw = skbn->data; - /* Copy AX.25 headers */ - memcpy(skbn->data, skbo->data, nhdrlen); - skb_pull(skbn, nhdrlen); - skb_pull(skbo, hdrlen); - /* Copy data from the fragments */ - do { + while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) { memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len); kfree_skb(skbo, FREE_READ); - } while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL); + } ax25->fraglen = 0; @@ -188,11 +169,13 @@ return (*func)(skb, ax25); } - if (ax25->sk != NULL && ax25->ax25_dev->values[AX25_VALUES_CONMODE] == 2 && ax25->sk->protocol == pid) { - if (sock_queue_rcv_skb(ax25->sk, skb) == 0) - queued = 1; - else - ax25->condition |= AX25_COND_OWN_RX_BUSY; + if (ax25->sk != NULL && ax25->ax25_dev->values[AX25_VALUES_CONMODE] == 2) { + if ((!ax25->pidincl && ax25->sk->protocol == pid) || ax25->pidincl) { + if (sock_queue_rcv_skb(ax25->sk, skb) == 0) + queued = 1; + else + ax25->condition |= AX25_COND_OWN_RX_BUSY; + } } return queued; @@ -256,7 +239,7 @@ return 0; } - if (call_in_firewall(PF_AX25, skb->dev, skb->h.raw, NULL,&skb) != FW_ACCEPT) { + if (call_in_firewall(PF_AX25, skb->dev, skb->h.raw, NULL, &skb) != FW_ACCEPT) { kfree_skb(skb, FREE_READ); return 0; } @@ -445,7 +428,7 @@ if (dp.ndigi == 0) { if (ax25->digipeat != NULL) { - kfree_s(ax25->digipeat, sizeof(ax25_digi)); + kfree(ax25->digipeat); ax25->digipeat = NULL; } } else { diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_ip.c linux/net/ax25/ax25_ip.c --- linux-2.1.30/net/ax25/ax25_ip.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/ax25_ip.c Tue Mar 18 20:18:52 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -94,7 +91,7 @@ *buff++ = AX25_P_ARP; break; default: - printk(KERN_ERR "AX.25 wrong protocol type 0x%x2.2\n", type); + printk(KERN_ERR "AX.25: ax25_encapsulate - wrong protocol type 0x%x2.2\n", type); *buff++ = 0; break; } @@ -138,7 +135,7 @@ * gets fixed. */ if ((ourskb = skb_copy(skb, GFP_ATOMIC)) == NULL) { - dev_kfree_skb(skb, FREE_WRITE); + kfree_skb(skb, FREE_WRITE); return 1; } @@ -163,12 +160,15 @@ bp[14] |= AX25_EBIT; bp[14] |= AX25_SSSID_SPARE; - ax25_dg_build_path(skb, (ax25_address *)(bp + 1), dev); + if ((ourskb = ax25_dg_build_path(skb, (ax25_address *)(bp + 1), dev)) == NULL) { + kfree_skb(skb, FREE_WRITE); + return 1; + } - skb->dev = dev; - skb->priority = SOPRI_NORMAL; + ourskb->dev = dev; + ourskb->priority = SOPRI_NORMAL; - ax25_queue_xmit(skb); + ax25_queue_xmit(ourskb); return 1; } diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_out.c linux/net/ax25/ax25_out.c --- linux-2.1.30/net/ax25/ax25_out.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/ax25_out.c Thu Mar 27 20:28:06 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -157,7 +154,7 @@ if ((skbn = alloc_skb(paclen + 2 + frontlen, GFP_ATOMIC)) == NULL) { restore_flags(flags); - printk(KERN_DEBUG "ax25_output: alloc_skb returned NULL\n"); + printk(KERN_CRIT "AX.25: ax25_output - out of memory\n"); return; } @@ -314,7 +311,9 @@ void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type) { + struct sk_buff *skbn; unsigned char *ptr; + int headroom; if (ax25->ax25_dev == NULL) { if (ax25->sk != NULL) { @@ -328,13 +327,24 @@ return; } - if (skb_headroom(skb) < ax25_addr_size(ax25->digipeat)) { - printk(KERN_CRIT "ax25_transmit_buffer: not enough room for digi-peaters\n"); + headroom = ax25_addr_size(ax25->digipeat); + + if (skb_headroom(skb) < headroom) { + if ((skbn = skb_realloc_headroom(skb, headroom)) == NULL) { + printk(KERN_CRIT "AX.25: ax25_transmit_buffer - out of memory\n"); + kfree_skb(skb, FREE_WRITE); + return; + } + + if (skb->sk != NULL) + skb_set_owner_w(skbn, skb->sk); + kfree_skb(skb, FREE_WRITE); - return; + skb = skbn; } - ptr = skb_push(skb, ax25_addr_size(ax25->digipeat)); + ptr = skb_push(skb, headroom); + ax25_addr_build(ptr, &ax25->source_addr, &ax25->dest_addr, ax25->digipeat, type, ax25->modulus); skb->dev = ax25->ax25_dev->dev; @@ -352,7 +362,7 @@ unsigned char *ptr; if (call_out_firewall(PF_AX25, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT) { - dev_kfree_skb(skb, FREE_WRITE); + kfree_skb(skb, FREE_WRITE); return; } diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_route.c linux/net/ax25/ax25_route.c --- linux-2.1.30/net/ax25/ax25_route.c Fri Mar 7 14:49:12 1997 +++ linux/net/ax25/ax25_route.c Tue Mar 18 20:20:24 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -99,15 +96,15 @@ if (ax25_route_list == s) { ax25_route_list = s->next; if (s->digipeat != NULL) - kfree_s(s->digipeat, sizeof(ax25_digi)); - kfree_s(s, sizeof(ax25_route)); + kfree(s->digipeat); + kfree(s); } else { for (t = ax25_route_list; t != NULL; t = t->next) { if (t->next == s) { t->next = s->next; if (s->digipeat != NULL) - kfree_s(s->digipeat, sizeof(ax25_digi)); - kfree_s(s, sizeof(ax25_route)); + kfree(s->digipeat); + kfree(s); break; } } @@ -137,7 +134,7 @@ for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) { if (ax25cmp(&ax25_rt->callsign, &route.dest_addr) == 0 && ax25_rt->dev == ax25_dev->dev) { if (ax25_rt->digipeat != NULL) { - kfree_s(ax25_rt->digipeat, sizeof(ax25_digi)); + kfree(ax25_rt->digipeat); ax25_rt->digipeat = NULL; } if (route.digi_count != 0) { @@ -161,7 +158,7 @@ ax25_rt->ip_mode = ' '; if (route.digi_count != 0) { if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { - kfree_s(ax25_rt, sizeof(ax25_route)); + kfree(ax25_rt); return -ENOMEM; } ax25_rt->digipeat->lastrepeat = -1; @@ -191,15 +188,15 @@ if (ax25_route_list == s) { ax25_route_list = s->next; if (s->digipeat != NULL) - kfree_s(s->digipeat, sizeof(ax25_digi)); - kfree_s(s, sizeof(ax25_route)); + kfree(s->digipeat); + kfree(s); } else { for (t = ax25_route_list; t != NULL; t = t->next) { if (t->next == s) { t->next = s->next; if (s->digipeat != NULL) - kfree_s(s->digipeat, sizeof(ax25_digi)); - kfree_s(s, sizeof(ax25_route)); + kfree(s->digipeat); + kfree(s); break; } } @@ -413,8 +410,9 @@ ax25_adjust_path(addr, ax25->digipeat); } -void ax25_dg_build_path(struct sk_buff *skb, ax25_address *addr, struct device *dev) +struct sk_buff *ax25_dg_build_path(struct sk_buff *skb, ax25_address *addr, struct device *dev) { + struct sk_buff *skbn; ax25_route *ax25_rt; ax25_digi digipeat; ax25_address src, dest; @@ -424,10 +422,10 @@ skb_pull(skb, 1); /* skip KISS command */ if ((ax25_rt = ax25_find_route(addr, dev)) == NULL) - return; + return skb; if (ax25_rt->digipeat == NULL) - return; + return skb; digipeat = *ax25_rt->digipeat; @@ -436,8 +434,17 @@ len = ax25_rt->digipeat->ndigi * AX25_ADDR_LEN; if (skb_headroom(skb) < len) { - printk(KERN_CRIT "ax25_dg_build_path: not enough headroom for digis in skb\n"); - return; + if ((skbn = skb_realloc_headroom(skb, len)) == NULL) { + printk(KERN_CRIT "AX.25: ax25_dg_build_path - out of memory\n"); + return NULL; + } + + if (skb->sk != NULL) + skb_set_owner_w(skbn, skb->sk); + + kfree_skb(skb, FREE_WRITE); + + skb = skbn; } memcpy(&dest, skb->data + 0, AX25_ADDR_LEN); @@ -446,6 +453,8 @@ bp = skb_push(skb, len); ax25_addr_build(bp, &src, &dest, ax25_rt->digipeat, AX25_COMMAND, AX25_MODULUS); + + return skb; } /* @@ -476,9 +485,9 @@ ax25_rt = ax25_rt->next; if (s->digipeat != NULL) - kfree_s(s->digipeat, sizeof(ax25_digi)); + kfree(s->digipeat); - kfree_s(s, sizeof(ax25_route)); + kfree(s); } } diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_std_in.c linux/net/ax25/ax25_std_in.c --- linux-2.1.30/net/ax25/ax25_std_in.c Fri Mar 7 14:49:12 1997 +++ linux/net/ax25/ax25_std_in.c Sat Mar 15 20:13:36 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_std_subr.c linux/net/ax25/ax25_std_subr.c --- linux-2.1.30/net/ax25/ax25_std_subr.c Fri Mar 7 14:49:12 1997 +++ linux/net/ax25/ax25_std_subr.c Sat Mar 15 20:13:25 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_std_timer.c linux/net/ax25/ax25_std_timer.c --- linux-2.1.30/net/ax25/ax25_std_timer.c Fri Mar 7 14:49:12 1997 +++ linux/net/ax25/ax25_std_timer.c Sat Mar 15 20:13:08 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_subr.c linux/net/ax25/ax25_subr.c --- linux-2.1.30/net/ax25/ax25_subr.c Fri Mar 7 14:49:12 1997 +++ linux/net/ax25/ax25_subr.c Sat Mar 15 20:12:55 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -289,6 +286,9 @@ */ void ax25_calculate_rtt(ax25_cb *ax25) { + if (ax25->backoff == 0) + return; + if (ax25->t1timer > 0 && ax25->n2count == 0) ax25->rtt = (9 * ax25->rtt + ax25->t1 - ax25->t1timer) / 10; diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_timer.c linux/net/ax25/ax25_timer.c --- linux-2.1.30/net/ax25/ax25_timer.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/ax25_timer.c Sat Mar 15 20:12:44 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: diff -u --recursive --new-file linux-2.1.30/net/ax25/ax25_uid.c linux/net/ax25/ax25_uid.c --- linux-2.1.30/net/ax25/ax25_uid.c Fri Mar 7 14:49:13 1997 +++ linux/net/ax25/ax25_uid.c Sun Mar 16 11:05:02 1997 @@ -1,9 +1,6 @@ /* * AX.25 release 036 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -110,14 +107,14 @@ if ((s = ax25_uid_list) == ax25_uid) { ax25_uid_list = s->next; restore_flags(flags); - kfree_s(ax25_uid, sizeof(ax25_uid_assoc)); + kfree(ax25_uid); return 0; } while (s != NULL && s->next != NULL) { if (s->next == ax25_uid) { s->next = ax25_uid->next; restore_flags(flags); - kfree_s(ax25_uid, sizeof(ax25_uid_assoc)); + kfree(ax25_uid); return 0; } s = s->next; @@ -180,7 +177,7 @@ s = ax25_uid; ax25_uid = ax25_uid->next; - kfree_s(s, sizeof(ax25_uid_assoc)); + kfree(s); } } diff -u --recursive --new-file linux-2.1.30/net/ax25/sysctl_net_ax25.c linux/net/ax25/sysctl_net_ax25.c --- linux-2.1.30/net/ax25/sysctl_net_ax25.c Thu Mar 27 19:43:26 1997 +++ linux/net/ax25/sysctl_net_ax25.c Thu Mar 27 20:29:36 1997 @@ -5,6 +5,7 @@ * Added /proc/sys/net/ax25 directory entry (empty =) ). [MS] */ +#include #include #include #include @@ -122,7 +123,7 @@ ax25_table[n].proc_handler = NULL; memcpy(ax25_dev->systable, ax25_param_table, sizeof(ax25_dev->systable)); - + #ifndef CONFIG_AX25_DAMA_SLAVE /* * We do not wish to have a representation of this parameter @@ -150,7 +151,7 @@ { unregister_sysctl_table(ax25_table_header); - kfree_s(ax25_table, ax25_table_size); + kfree(ax25_table); ax25_dir_table[0].child = NULL; } diff -u --recursive --new-file linux-2.1.30/net/lapb/lapb_iface.c linux/net/lapb/lapb_iface.c --- linux-2.1.30/net/lapb/lapb_iface.c Fri Mar 7 14:49:16 1997 +++ linux/net/lapb/lapb_iface.c Thu Mar 20 19:26:28 1997 @@ -49,7 +49,7 @@ */ static void lapb_free_cb(lapb_cb *lapb) { - kfree_s(lapb, sizeof(lapb_cb)); + kfree(lapb); MOD_DEC_USE_COUNT; } @@ -122,7 +122,7 @@ { lapb_cb *lapb; - if ((lapb = (lapb_cb *)kmalloc(sizeof(*lapb), GFP_ATOMIC)) == NULL) + if ((lapb = kmalloc(sizeof(*lapb), GFP_ATOMIC)) == NULL) return NULL; MOD_INC_USE_COUNT; @@ -403,6 +403,9 @@ } #ifdef MODULE +MODULE_AUTHOR("Jonathan Naylor "); +MODULE_DESCRIPTION("The X.25 Link Access Procedure B link layer protocol"); + int init_module(void) { lapb_proto_init(NULL); diff -u --recursive --new-file linux-2.1.30/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c --- linux-2.1.30/net/netrom/af_netrom.c Thu Mar 27 19:43:33 1997 +++ linux/net/netrom/af_netrom.c Thu Mar 27 21:15:17 1997 @@ -1,9 +1,6 @@ /* * NET/ROM release 006 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -30,6 +27,7 @@ * NET/ROM 005 Jonathan(G4KLX) Linux 2.1 * Alan(GW4PTS) Started POSIXisms * NET/ROM 006 Alan(GW4PTS) Brought in line with the ANK changes + * Jonathan(G4KLX) Removed hdrincl. */ #include @@ -65,6 +63,9 @@ #include #include +int nr_ndevs = 4; +MODULE_PARM(nr_ndevs, "i"); + int sysctl_netrom_default_path_quality = NR_DEFAULT_QUAL; int sysctl_netrom_obsolescence_count_initialiser = NR_DEFAULT_OBS; int sysctl_netrom_network_ttl_initialiser = NR_DEFAULT_TTL; @@ -85,7 +86,7 @@ static void nr_free_sock(struct sock *sk) { - kfree_s(sk->protinfo.nr, sizeof(*sk->protinfo.nr)); + kfree(sk->protinfo.nr); sk_free(sk); @@ -100,7 +101,7 @@ if ((sk = sk_alloc(GFP_ATOMIC)) == NULL) return NULL; - if ((nr = (nr_cb *)kmalloc(sizeof(*nr), GFP_ATOMIC)) == NULL) { + if ((nr = kmalloc(sizeof(*nr), GFP_ATOMIC)) == NULL) { sk_free(sk); return NULL; } @@ -460,10 +461,6 @@ sk->protinfo.nr->idle = opt * 60 * NR_SLOWHZ; return 0; - case NETROM_HDRINCL: - sk->protinfo.nr->hdrincl = opt ? 1 : 0; - return 0; - default: return -ENOPROTOOPT; } @@ -503,10 +500,6 @@ val = sk->protinfo.nr->idle / (NR_SLOWHZ * 60); break; - case NETROM_HDRINCL: - val = sk->protinfo.nr->hdrincl; - break; - default: return -ENOPROTOOPT; } @@ -612,7 +605,6 @@ nr->device = osk->protinfo.nr->device; nr->bpqext = osk->protinfo.nr->bpqext; - nr->hdrincl = osk->protinfo.nr->hdrincl; return sk; } @@ -1120,7 +1112,6 @@ return len; } - static int nr_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) { @@ -1142,12 +1133,8 @@ if ((skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &er)) == NULL) return er; - if (!sk->protinfo.nr->hdrincl) { - skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN); - skb->h.raw = skb->data; - } - - copied = skb->len; + skb->h.raw = skb->data; + copied = skb->len; if (copied > size) { copied = size; @@ -1353,28 +1340,32 @@ }; #endif -static struct device dev_nr[] = { - {"nr0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, nr_init}, - {"nr1", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, nr_init}, - {"nr2", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, nr_init}, - {"nr3", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, nr_init} -}; +static struct device *dev_nr; void nr_proto_init(struct net_proto *pro) { int i; + if ((dev_nr = kmalloc(nr_ndevs * sizeof(struct device), GFP_KERNEL)) == NULL) { + printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n"); + return; + } + + memset(dev_nr, 0x00, nr_ndevs * sizeof(struct device)); + + for (i = 0; i < nr_ndevs; i++) { + dev_nr[i].name = kmalloc(20, GFP_KERNEL); + sprintf(dev_nr[i].name, "nr%d", i); + dev_nr[i].init = nr_init; + register_netdev(&dev_nr[i]); + } + sock_register(&nr_family_ops); register_netdevice_notifier(&nr_dev_notifier); printk(KERN_INFO "G4KLX NET/ROM for Linux. Version 0.6 for AX25.035 Linux 2.1\n"); - if (!ax25_protocol_register(AX25_P_NETROM, nr_route_frame)) - printk(KERN_ERR "NET/ROM unable to register protocol with AX.25\n"); - if (!ax25_linkfail_register(nr_link_failed)) - printk(KERN_ERR "NET/ROM unable to register linkfail handler with AX.25\n"); - - for (i = 0; i < 4; i++) - register_netdev(&dev_nr[i]); + ax25_protocol_register(AX25_P_NETROM, nr_route_frame); + ax25_linkfail_register(nr_link_failed); nr_register_sysctl(); @@ -1388,6 +1379,9 @@ #ifdef MODULE EXPORT_NO_SYMBOLS; +MODULE_AUTHOR("Jonathan Naylor G4KLX "); +MODULE_DESCRIPTION("The amateur radio NET/ROM network and transport layer protocol"); + int init_module(void) { nr_proto_init(NULL); @@ -1415,13 +1409,16 @@ sock_unregister(AF_NETROM); - for (i = 0; i < 4; i++) { + for (i = 0; i < nr_ndevs; i++) { if (dev_nr[i].priv != NULL) { kfree(dev_nr[i].priv); dev_nr[i].priv = NULL; unregister_netdev(&dev_nr[i]); } + kfree(dev_nr[i].name); } + + kfree(dev_nr); } #endif diff -u --recursive --new-file linux-2.1.30/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c --- linux-2.1.30/net/netrom/nr_dev.c Thu Mar 27 19:43:33 1997 +++ linux/net/netrom/nr_dev.c Tue Mar 18 20:15:10 1997 @@ -1,9 +1,6 @@ /* * NET/ROM release 006 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -123,7 +120,7 @@ struct sk_buff *skbn; unsigned char *bp = skb->data; - if (!arp_find(bp + 7, skb)) { + if (arp_find(bp + 7, skb)) { kfree_skb(skb, FREE_WRITE); return 1; } @@ -203,7 +200,7 @@ return 0; if (!dev->start) { - printk(KERN_ERR "netrom: xmit call when iface is down\n"); + printk(KERN_ERR "NET/ROM: nr_xmit - called when iface is down\n"); return 1; } diff -u --recursive --new-file linux-2.1.30/net/netrom/nr_in.c linux/net/netrom/nr_in.c --- linux-2.1.30/net/netrom/nr_in.c Fri Mar 7 14:48:20 1997 +++ linux/net/netrom/nr_in.c Tue Mar 25 16:32:29 1997 @@ -1,9 +1,6 @@ /* * NET/ROM release 006 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -23,6 +20,7 @@ * NET/ROM 003 Jonathan(G4KLX) Added NET/ROM fragment reception. * Darryl(G7LED) Added missing INFO with NAK case, optimized * INFOACK handling, removed reconnect on error. + * NET/ROM 006 Jonathan(G4KLX) Hdrincl removal changes. */ #include @@ -54,6 +52,8 @@ { struct sk_buff *skbo, *skbn = skb; + skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN); + if (more) { sk->protinfo.nr->fraglen += skb->len; skb_queue_tail(&sk->protinfo.nr->frag_queue, skb); @@ -69,12 +69,7 @@ skbn->h.raw = skbn->data; - skbo = skb_dequeue(&sk->protinfo.nr->frag_queue); - memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len); - kfree_skb(skbo, FREE_READ); - while ((skbo = skb_dequeue(&sk->protinfo.nr->frag_queue)) != NULL) { - skb_pull(skbo, NR_NETWORK_LEN + NR_TRANSPORT_LEN); memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len); kfree_skb(skbo, FREE_READ); } diff -u --recursive --new-file linux-2.1.30/net/netrom/nr_out.c linux/net/netrom/nr_out.c --- linux-2.1.30/net/netrom/nr_out.c Fri Mar 7 14:48:20 1997 +++ linux/net/netrom/nr_out.c Sat Mar 15 20:17:00 1997 @@ -1,9 +1,6 @@ /* * NET/ROM release 006 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: diff -u --recursive --new-file linux-2.1.30/net/netrom/nr_route.c linux/net/netrom/nr_route.c --- linux-2.1.30/net/netrom/nr_route.c Thu Mar 27 19:43:33 1997 +++ linux/net/netrom/nr_route.c Thu Mar 27 20:18:59 1997 @@ -1,9 +1,6 @@ /* * NET/ROM release 006 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -91,7 +88,7 @@ return 0; if (nr_neigh == NULL) { - if ((nr_neigh = (struct nr_neigh *)kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) + if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) return -ENOMEM; nr_neigh->callsign = *ax25; @@ -105,7 +102,7 @@ if (ax25_digi != NULL && ax25_digi->ndigi > 0) { if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) { - kfree_s(nr_neigh, sizeof(*nr_neigh)); + kfree(nr_neigh); return -ENOMEM; } *nr_neigh->digipeat = *ax25_digi; @@ -124,7 +121,7 @@ nr_neigh->quality = quality; if (nr_node == NULL) { - if ((nr_node = (struct nr_node *)kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL) + if ((nr_node = kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL) return -ENOMEM; nr_node->callsign = *nr; @@ -252,7 +249,7 @@ if ((s = nr_node_list) == nr_node) { nr_node_list = nr_node->next; restore_flags(flags); - kfree_s(nr_node, sizeof(struct nr_node)); + kfree(nr_node); return; } @@ -260,7 +257,7 @@ if (s->next == nr_node) { s->next = nr_node->next; restore_flags(flags); - kfree_s(nr_node, sizeof(struct nr_node)); + kfree(nr_node); return; } @@ -282,8 +279,8 @@ nr_neigh_list = nr_neigh->next; restore_flags(flags); if (nr_neigh->digipeat != NULL) - kfree_s(nr_neigh->digipeat, sizeof(ax25_digi)); - kfree_s(nr_neigh, sizeof(struct nr_neigh)); + kfree(nr_neigh->digipeat); + kfree(nr_neigh); return; } @@ -292,8 +289,8 @@ s->next = nr_neigh->next; restore_flags(flags); if (nr_neigh->digipeat != NULL) - kfree_s(nr_neigh->digipeat, sizeof(ax25_digi)); - kfree_s(nr_neigh, sizeof(struct nr_neigh)); + kfree(nr_neigh->digipeat); + kfree(nr_neigh); return; } @@ -370,7 +367,7 @@ } } - if ((nr_neigh = (struct nr_neigh *)kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) + if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) return -ENOMEM; nr_neigh->callsign = *callsign; @@ -384,7 +381,7 @@ if (ax25_digi != NULL && ax25_digi->ndigi > 0) { if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) { - kfree_s(nr_neigh, sizeof(*nr_neigh)); + kfree(nr_neigh); return -ENOMEM; } *nr_neigh->digipeat = *ax25_digi; @@ -688,6 +685,7 @@ if (ax25 != NULL && call_in_firewall(PF_NETROM, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT) return 0; + if (ax25 == NULL && call_out_firewall(PF_NETROM, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT) return 0; diff -u --recursive --new-file linux-2.1.30/net/netrom/nr_subr.c linux/net/netrom/nr_subr.c --- linux-2.1.30/net/netrom/nr_subr.c Fri Mar 7 14:48:20 1997 +++ linux/net/netrom/nr_subr.c Tue Mar 18 20:14:14 1997 @@ -1,9 +1,6 @@ /* * NET/ROM release 006 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: @@ -158,7 +155,7 @@ case NR_INFOACK: break; default: - printk(KERN_ERR "nr_write_internal: invalid frame type %d\n", frametype); + printk(KERN_ERR "NET/ROM: nr_write_internal - invalid frame type %d\n", frametype); return; } diff -u --recursive --new-file linux-2.1.30/net/netrom/nr_timer.c linux/net/netrom/nr_timer.c --- linux-2.1.30/net/netrom/nr_timer.c Thu Mar 27 19:43:33 1997 +++ linux/net/netrom/nr_timer.c Sat Mar 15 20:17:29 1997 @@ -1,9 +1,6 @@ /* * NET/ROM release 006 * - * 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. - * * This code REQUIRES 2.1.15 or higher/ NET3.038 * * This module: diff -u --recursive --new-file linux-2.1.30/net/rose/af_rose.c linux/net/rose/af_rose.c --- linux-2.1.30/net/rose/af_rose.c Thu Mar 27 19:43:34 1997 +++ linux/net/rose/af_rose.c Thu Mar 27 21:40:04 1997 @@ -1,8 +1,5 @@ /* - * Rose release 001 - * - * 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. + * ROSE release 002 * * This code REQUIRES 2.1.15 or higher/ NET3.038 * @@ -13,10 +10,13 @@ * 2 of the License, or (at your option) any later version. * * History - * Rose 001 Jonathan(G4KLX) Cloned from af_netrom.c. + * ROSE 001 Jonathan(G4KLX) Cloned from af_netrom.c. * Alan(GW4PTS) Hacked up for newer API stuff * Terry (VK2KTJ) Added support for variable length * address masks. + * ROSE 002 Jonathan(G4KLX) Changed hdrincl to qbitincl. + * Added random number facilities entry. + * Variable number of ROSE devices. */ #include @@ -53,6 +53,9 @@ #include #include +int rose_ndevs = 6; +MODULE_PARM(rose_ndevs, "i"); + int sysctl_rose_restart_request_timeout = ROSE_DEFAULT_T0; int sysctl_rose_call_request_timeout = ROSE_DEFAULT_T1; int sysctl_rose_reset_request_timeout = ROSE_DEFAULT_T2; @@ -71,7 +74,7 @@ ax25_address rose_callsign; /* - * Convert a Rose address into text. + * Convert a ROSE address into text. */ char *rose2asc(rose_address *addr) { @@ -93,7 +96,7 @@ } /* - * Compare two Rose addresses, 0 == equal. + * Compare two ROSE addresses, 0 == equal. */ int rosecmp(rose_address *addr1, rose_address *addr2) { @@ -107,7 +110,7 @@ } /* - * Compare two Rose addresses for only mask digits, 0 == equal. + * Compare two ROSE addresses for only mask digits, 0 == equal. */ int rosecmpm(rose_address *addr1, rose_address *addr2, unsigned short mask) { @@ -133,7 +136,7 @@ static void rose_free_sock(struct sock *sk) { - kfree_s(sk->protinfo.rose, sizeof(*sk->protinfo.rose)); + kfree(sk->protinfo.rose); sk_free(sk); @@ -148,7 +151,7 @@ if ((sk = sk_alloc(GFP_ATOMIC)) == NULL) return NULL; - if ((rose = (rose_cb *)kmalloc(sizeof(*rose), GFP_ATOMIC)) == NULL) { + if ((rose = kmalloc(sizeof(*rose), GFP_ATOMIC)) == NULL) { sk_free(sk); return NULL; } @@ -194,6 +197,27 @@ } /* + * Kill all bound sockets on a broken link layer connection to a + * particular neighbour. + */ +void rose_kill_by_neigh(struct rose_neigh *neigh) +{ + struct sock *s; + + for (s = rose_list; s != NULL; s = s->next) { + if (s->protinfo.rose->neighbour == neigh) { + s->protinfo.rose->state = ROSE_STATE_0; + s->protinfo.rose->neighbour = NULL; + s->state = TCP_CLOSE; + s->err = ENETUNREACH; + s->shutdown |= SEND_SHUTDOWN; + s->state_change(s); + s->dead = 1; + } + } +} + +/* * Kill all bound sockets on a dropped device. */ static void rose_kill_by_device(struct device *dev) @@ -223,9 +247,15 @@ if (event != NETDEV_DOWN) return NOTIFY_DONE; - rose_kill_by_device(dev); - rose_rt_device_down(dev); - rose_link_device_down(dev); + switch (dev->type) { + case ARPHRD_ROSE: + rose_kill_by_device(dev); + break; + case ARPHRD_AX25: + rose_link_device_down(dev); + rose_rt_device_down(dev); + break; + } return NOTIFY_DONE; } @@ -250,7 +280,7 @@ * Find a socket that wants to accept the Call Request we just * received. */ -static struct sock *rose_find_listener(ax25_address *call) +static struct sock *rose_find_listener(rose_address *addr, ax25_address *call) { unsigned long flags; struct sock *s; @@ -259,14 +289,14 @@ cli(); for (s = rose_list; s != NULL; s = s->next) { - if (ax25cmp(&s->protinfo.rose->source_call, call) == 0 && s->protinfo.rose->source_ndigis == 0 && s->state == TCP_LISTEN) { + if (rosecmp(&s->protinfo.rose->source_addr, addr) == 0 && ax25cmp(&s->protinfo.rose->source_call, call) == 0 && s->protinfo.rose->source_ndigis == 0 && s->state == TCP_LISTEN) { restore_flags(flags); return s; } } for (s = rose_list; s != NULL; s = s->next) { - if (ax25cmp(&s->protinfo.rose->source_call, &null_ax25_address) == 0 && s->state == TCP_LISTEN) { + if (rosecmp(&s->protinfo.rose->source_addr, addr) == 0 && ax25cmp(&s->protinfo.rose->source_call, &null_ax25_address) == 0 && s->state == TCP_LISTEN) { restore_flags(flags); return s; } @@ -277,7 +307,7 @@ } /* - * Find a connected Rose socket given my LCI and device. + * Find a connected ROSE socket given my LCI and device. */ struct sock *rose_find_socket(unsigned int lci, struct device *dev) { @@ -372,11 +402,11 @@ /* * Handling for system calls applied via the various interfaces to a - * Rose socket object. + * ROSE socket object. */ /* - * dl1bke 960311: set parameters for existing Rose connections, + * dl1bke 960311: set parameters for existing ROSE connections, * includes a KILL command to abort any connection. * VERY useful for debugging ;-) */ @@ -506,8 +536,8 @@ sk->protinfo.rose->idle = opt * 60 * ROSE_SLOWHZ; return 0; - case ROSE_HDRINCL: - sk->protinfo.rose->hdrincl = opt ? 1 : 0; + case ROSE_QBITINCL: + sk->protinfo.rose->qbitincl = opt ? 1 : 0; return 0; default: @@ -549,8 +579,8 @@ val = sk->protinfo.rose->idle / (ROSE_SLOWHZ * 60); break; - case ROSE_HDRINCL: - val = sk->protinfo.rose->hdrincl; + case ROSE_QBITINCL: + val = sk->protinfo.rose->qbitincl; break; default: @@ -652,8 +682,8 @@ rose->hb = osk->protinfo.rose->hb; rose->idle = osk->protinfo.rose->idle; - rose->device = osk->protinfo.rose->device; - rose->hdrincl = osk->protinfo.rose->hdrincl; + rose->device = osk->protinfo.rose->device; + rose->qbitincl = osk->protinfo.rose->qbitincl; return sk; } @@ -734,7 +764,7 @@ return -EINVAL; if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) { - SOCK_DEBUG(sk, "Rose: bind failed: invalid address\n"); + SOCK_DEBUG(sk, "ROSE: bind failed: invalid address\n"); return -EADDRNOTAVAIL; } @@ -758,7 +788,7 @@ rose_insert_socket(sk); sk->zapped = 0; - SOCK_DEBUG(sk, "Rose: socket is bound\n"); + SOCK_DEBUG(sk, "ROSE: socket is bound\n"); return 0; } @@ -817,6 +847,7 @@ sk->protinfo.rose->dest_digi = addr->srose_digi; } sk->protinfo.rose->lci = rose_new_lci(sk->protinfo.rose->neighbour->dev); + sk->protinfo.rose->rand = ((int)sk->protinfo.rose & 0xFFFF) + sk->protinfo.rose->lci; /* Move to connecting socket, start sending Connect Requests */ sock->state = SS_CONNECTING; @@ -952,7 +983,7 @@ { struct sock *sk; struct sock *make; - rose_cb rose; + struct rose_facilities facilities; skb->sk = NULL; /* Initially we don't know who it's for */ @@ -963,11 +994,11 @@ /* * XXX This is an error. */ - if (!rose_parse_facilities(skb, &rose)) { + if (!rose_parse_facilities(skb, &facilities)) { return 0; } - sk = rose_find_listener(&rose.source_call); + sk = rose_find_listener(&facilities.source_addr, &facilities.source_call); /* * We can't accept the Call Request. @@ -981,14 +1012,14 @@ make->state = TCP_ESTABLISHED; make->protinfo.rose->lci = lci; - make->protinfo.rose->dest_addr = rose.dest_addr; - make->protinfo.rose->dest_call = rose.dest_call; - make->protinfo.rose->dest_ndigis = rose.dest_ndigis; - make->protinfo.rose->dest_digi = rose.dest_digi; - make->protinfo.rose->source_addr = rose.source_addr; - make->protinfo.rose->source_call = rose.source_call; - make->protinfo.rose->source_ndigis = rose.source_ndigis; - make->protinfo.rose->source_digi = rose.source_digi; + make->protinfo.rose->dest_addr = facilities.dest_addr; + make->protinfo.rose->dest_call = facilities.dest_call; + make->protinfo.rose->dest_ndigis = facilities.dest_ndigis; + make->protinfo.rose->dest_digi = facilities.dest_digi; + make->protinfo.rose->source_addr = facilities.source_addr; + make->protinfo.rose->source_call = facilities.source_call; + make->protinfo.rose->source_ndigis = facilities.source_ndigis; + make->protinfo.rose->source_digi = facilities.source_digi; make->protinfo.rose->neighbour = neigh; make->protinfo.rose->device = dev; @@ -1024,7 +1055,7 @@ struct sockaddr_rose srose; struct sk_buff *skb; unsigned char *asmptr; - int size; + int size, qbit = 0; if (msg->msg_flags & ~MSG_DONTWAIT) return -EINVAL; @@ -1037,7 +1068,7 @@ return -EPIPE; } - if (sk->protinfo.rose->device == NULL) + if (sk->protinfo.rose->neighbour == NULL) return -ENETUNREACH; if (usrose != NULL) { @@ -1067,44 +1098,55 @@ srose.srose_digi = sk->protinfo.rose->dest_digi; } } - SOCK_DEBUG(sk, "Rose: sendto: Addresses built.\n"); + + SOCK_DEBUG(sk, "ROSE: sendto: Addresses built.\n"); /* Build a packet */ - SOCK_DEBUG(sk, "Rose: sendto: building packet.\n"); + SOCK_DEBUG(sk, "ROSE: sendto: building packet.\n"); size = len + AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN; if ((skb = sock_alloc_send_skb(sk, size, 0, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL) return err; - skb_reserve(skb, size - len); + skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN); /* - * Push down the Rose header + * Put the data on the end */ + SOCK_DEBUG(sk, "ROSE: Appending user data\n"); - asmptr = skb_push(skb, ROSE_MIN_LEN); - SOCK_DEBUG(sk, "Building Rose Header.\n"); + asmptr = skb->h.raw = skb_put(skb, len); - /* Build a Rose Transport header */ + memcpy_fromiovec(asmptr, msg->msg_iov, len); - *asmptr++ = ((sk->protinfo.rose->lci >> 8) & 0x0F) | ROSE_GFI; - *asmptr++ = (sk->protinfo.rose->lci >> 0) & 0xFF; - *asmptr++ = ROSE_DATA; - SOCK_DEBUG(sk, "Built header.\n"); + /* + * If the Q BIT Include socket option is in force, the first + * byte of the user data is the logical value of the Q Bit. + */ + if (sk->protinfo.rose->qbitincl) { + qbit = skb->data[0]; + skb_pull(skb, 1); + } /* - * Put the data on the end + * Push down the ROSE header */ + asmptr = skb_push(skb, ROSE_MIN_LEN); - skb->h.raw = skb_put(skb, len); + SOCK_DEBUG(sk, "ROSE: Building Network Header.\n"); - asmptr = skb->h.raw; - SOCK_DEBUG(sk, "Rose: Appending user data\n"); + /* Build a ROSE Network header */ + asmptr[0] = ((sk->protinfo.rose->lci >> 8) & 0x0F) | ROSE_GFI; + asmptr[1] = (sk->protinfo.rose->lci >> 0) & 0xFF; + asmptr[2] = ROSE_DATA; - /* User data follows immediately after the Rose transport header */ - memcpy_fromiovec(asmptr, msg->msg_iov, len); - SOCK_DEBUG(sk, "Rose: Transmitting buffer\n"); + if (qbit) + asmptr[0] |= ROSE_Q_BIT; + + SOCK_DEBUG(sk, "ROSE: Built header.\n"); + SOCK_DEBUG(sk, "ROSE: Transmitting buffer\n"); + if (sk->state != TCP_ESTABLISHED) { kfree_skb(skb, FREE_WRITE); return -ENOTCONN; @@ -1121,7 +1163,8 @@ { struct sock *sk = sock->sk; struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name; - int copied; + int copied, qbit; + unsigned char *asmptr; struct sk_buff *skb; int er; @@ -1136,12 +1179,17 @@ if ((skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &er)) == NULL) return er; - if (!sk->protinfo.rose->hdrincl) { - skb_pull(skb, ROSE_MIN_LEN); - skb->h.raw = skb->data; + qbit = (skb->data[0] & ROSE_Q_BIT) == ROSE_Q_BIT; + + skb_pull(skb, ROSE_MIN_LEN); + + if (sk->protinfo.rose->qbitincl) { + asmptr = skb_push(skb, 1); + *asmptr = qbit; } - copied = skb->len; + skb->h.raw = skb->data; + copied = skb->len; if (copied > size) { copied = size; @@ -1371,14 +1419,7 @@ }; #endif -static struct device dev_rose[] = { - {"rose0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, rose_init}, - {"rose1", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, rose_init}, - {"rose2", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, rose_init}, - {"rose3", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, rose_init}, - {"rose4", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, rose_init}, - {"rose5", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, rose_init} -}; +static struct device *dev_rose; void rose_proto_init(struct net_proto *pro) { @@ -1386,17 +1427,26 @@ rose_callsign = null_ax25_address; - sock_register(&rose_family_ops); - register_netdevice_notifier(&rose_dev_notifier); - printk(KERN_INFO "G4KLX Rose for Linux. Version 0.1 for AX25.035 Linux 2.1\n"); + if ((dev_rose = kmalloc(rose_ndevs * sizeof(struct device), GFP_KERNEL)) == NULL) { + printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n"); + return; + } - if (!ax25_protocol_register(AX25_P_ROSE, rose_route_frame)) - printk(KERN_ERR "Rose unable to register protocol with AX.25\n"); - if (!ax25_linkfail_register(rose_link_failed)) - printk(KERN_ERR "Rose unable to register linkfail handler with AX.25\n"); + memset(dev_rose, 0x00, rose_ndevs * sizeof(struct device)); - for (i = 0; i < 6; i++) + for (i = 0; i < rose_ndevs; i++) { + dev_rose[i].name = kmalloc(20, GFP_KERNEL); + sprintf(dev_rose[i].name, "rose%d", i); + dev_rose[i].init = rose_init; register_netdev(&dev_rose[i]); + } + + sock_register(&rose_family_ops); + register_netdevice_notifier(&rose_dev_notifier); + printk(KERN_INFO "G4KLX ROSE for Linux. Version 0.2 for AX25.035 Linux 2.1\n"); + + ax25_protocol_register(AX25_P_ROSE, rose_route_frame); + ax25_linkfail_register(rose_link_failed); rose_register_sysctl(); @@ -1411,6 +1461,9 @@ #ifdef MODULE EXPORT_NO_SYMBOLS; +MODULE_AUTHOR("Jonathan Naylor G4KLX "); +MODULE_DESCRIPTION("The amateur radio ROSE network layer protocol"); + int init_module(void) { rose_proto_init(NULL); @@ -1442,13 +1495,16 @@ sock_unregister(AF_ROSE); - for (i = 0; i < 6; i++) { + for (i = 0; i < rose_ndevs; i++) { if (dev_rose[i].priv != NULL) { kfree(dev_rose[i].priv); dev_rose[i].priv = NULL; unregister_netdev(&dev_rose[i]); } + kfree(dev_rose[i].name); } + + kfree(dev_rose); } #endif diff -u --recursive --new-file linux-2.1.30/net/rose/rose_dev.c linux/net/rose/rose_dev.c --- linux-2.1.30/net/rose/rose_dev.c Thu Mar 27 19:43:34 1997 +++ linux/net/rose/rose_dev.c Tue Mar 25 10:57:36 1997 @@ -1,8 +1,5 @@ /* - * Rose release 001 - * - * 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. + * ROSE release 002 * * This code REQUIRES 2.1.15 or higher/ NET3.038 * @@ -13,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * History - * Rose 001 Jonathan(G4KLX) Cloned from nr_dev.c. + * ROSE 001 Jonathan(G4KLX) Cloned from nr_dev.c. * Hans(PE1AYX) Fixed interface to IP layer. */ @@ -52,7 +49,7 @@ #include /* - * Only allow IP over Rose frames through if the netrom device is up. + * Only allow IP over ROSE frames through if the netrom device is up. */ int rose_rx_ip(struct sk_buff *skb, struct device *dev) @@ -175,7 +172,7 @@ return 0; if (!dev->start) { - printk(KERN_ERR "rose: xmit call when iface is down\n"); + printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n"); return 1; } diff -u --recursive --new-file linux-2.1.30/net/rose/rose_in.c linux/net/rose/rose_in.c --- linux-2.1.30/net/rose/rose_in.c Fri Mar 7 14:49:17 1997 +++ linux/net/rose/rose_in.c Tue Mar 25 10:52:25 1997 @@ -1,8 +1,5 @@ /* - * Rose release 001 - * - * 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. + * ROSE release 002 * * This code REQUIRES 2.1.15 or higher/ NET3.038 * @@ -19,7 +16,7 @@ * easy to break; * * History - * Rose 001 Jonathan(G4KLX) Cloned from nr_in.c + * ROSE 001 Jonathan(G4KLX) Cloned from nr_in.c */ #include @@ -116,8 +113,7 @@ sk->dead = 1; break; - default: /* XXX */ - printk(KERN_WARNING "rose: unknown %02X in state 1\n", frametype); + default: break; } @@ -146,8 +142,7 @@ sk->dead = 1; break; - default: /* XXX */ - printk(KERN_WARNING "rose: unknown %02X in state 2\n", frametype); + default: break; } @@ -256,7 +251,7 @@ break; default: - printk(KERN_WARNING "rose: unknown %02X in state 3\n", frametype); + printk(KERN_WARNING "ROSE: unknown %02X in state 3\n", frametype); break; } @@ -297,8 +292,7 @@ sk->dead = 1; break; - default: /* XXX */ - printk(KERN_WARNING "rose: unknown %02X in state 4\n", frametype); + default: break; } diff -u --recursive --new-file linux-2.1.30/net/rose/rose_link.c linux/net/rose/rose_link.c --- linux-2.1.30/net/rose/rose_link.c Thu Mar 27 19:43:34 1997 +++ linux/net/rose/rose_link.c Thu Mar 27 20:15:32 1997 @@ -1,8 +1,5 @@ /* - * Rose release 001 - * - * 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. + * ROSE release 002 * * This code REQUIRES 2.1.15 or higher/ NET3.038 * @@ -13,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * History - * Rose 001 Jonathan(G4KLX) Cloned from rose_timer.c + * ROSE 001 Jonathan(G4KLX) Cloned from rose_timer.c */ #include @@ -62,7 +59,7 @@ } /* - * Rose Link Timer + * ROSE Link Timer * * This routine is called every 100ms. Decrement timer by this * amount - if expired then process the event. @@ -145,11 +142,11 @@ break; case ROSE_DIAGNOSTIC: - printk(KERN_WARNING "rose: diagnostic #%d\n", skb->data[3]); + printk(KERN_WARNING "ROSE: received diagnostic #%d\n", skb->data[3]); break; default: - printk(KERN_WARNING "rose: received unknown %02X with LCI 000\n", frametype); + printk(KERN_WARNING "ROSE: received unknown %02X with LCI 000\n", frametype); break; } @@ -278,8 +275,10 @@ { unsigned char *dptr; - if (call_fw_firewall(PF_ROSE, skb->dev, skb->data, NULL,&skb) != FW_ACCEPT) + if (call_fw_firewall(PF_ROSE, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT) { + kfree_skb(skb, FREE_WRITE); return; + } if (!rose_link_up(neigh)) neigh->restarted = 0; diff -u --recursive --new-file linux-2.1.30/net/rose/rose_out.c linux/net/rose/rose_out.c --- linux-2.1.30/net/rose/rose_out.c Fri Mar 7 14:48:21 1997 +++ linux/net/rose/rose_out.c Tue Mar 25 10:58:06 1997 @@ -1,8 +1,5 @@ /* - * Rose release 001 - * - * 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. + * ROSE release 002 * * This code REQUIRES 2.1.15 or higher/ NET3.038 * @@ -13,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * History - * Rose 001 Jonathan(G4KLX) Cloned from nr_out.c + * ROSE 001 Jonathan(G4KLX) Cloned from nr_out.c */ #include @@ -41,7 +38,7 @@ #include /* - * This is where all Rose frames pass; + * This is where all ROSE frames pass; */ void rose_output(struct sock *sk, struct sk_buff *skb) { diff -u --recursive --new-file linux-2.1.30/net/rose/rose_route.c linux/net/rose/rose_route.c --- linux-2.1.30/net/rose/rose_route.c Thu Mar 27 19:43:34 1997 +++ linux/net/rose/rose_route.c Thu Mar 27 19:46:30 1997 @@ -1,8 +1,5 @@ /* - * Rose release 001 - * - * 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. + * ROSE release 002 * * This code REQUIRES 2.1.15 or higher/ NET3.038 * @@ -13,9 +10,11 @@ * 2 of the License, or (at your option) any later version. * * History - * Rose 001 Jonathan(G4KLX) Cloned from nr_route.c. + * ROSE 001 Jonathan(G4KLX) Cloned from nr_route.c. * Terry(VK2KTJ) Added support for variable length * address masks. + * ROSE 002 Jonathan(G4KLX) Uprated through routing of packets. + * Routing loop detection. */ #include @@ -76,7 +75,7 @@ break; if (rose_neigh == NULL) { - if ((rose_neigh = (struct rose_neigh *)kmalloc(sizeof(*rose_neigh), GFP_ATOMIC)) == NULL) + if ((rose_neigh = kmalloc(sizeof(*rose_neigh), GFP_ATOMIC)) == NULL) return -ENOMEM; rose_neigh->callsign = rose_route->neighbour; @@ -92,7 +91,7 @@ if (rose_route->ndigis != 0) { if ((rose_neigh->digipeat = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) { - kfree_s(rose_neigh, sizeof(*rose_neigh)); + kfree(rose_neigh); return -ENOMEM; } rose_neigh->digipeat->ndigi = rose_route->ndigis; @@ -127,7 +126,7 @@ } /* create new node */ - if ((rose_node = (struct rose_node *)kmalloc(sizeof(*rose_node), GFP_ATOMIC)) == NULL) + if ((rose_node = kmalloc(sizeof(*rose_node), GFP_ATOMIC)) == NULL) return -ENOMEM; rose_node->address = rose_route->address; @@ -183,7 +182,7 @@ if ((s = rose_node_list) == rose_node) { rose_node_list = rose_node->next; restore_flags(flags); - kfree_s(rose_node, sizeof(struct rose_node)); + kfree(rose_node); return; } @@ -191,7 +190,7 @@ if (s->next == rose_node) { s->next = rose_node->next; restore_flags(flags); - kfree_s(rose_node, sizeof(struct rose_node)); + kfree(rose_node); return; } @@ -219,8 +218,8 @@ rose_neigh_list = rose_neigh->next; restore_flags(flags); if (rose_neigh->digipeat != NULL) - kfree_s(rose_neigh->digipeat, sizeof(ax25_digi)); - kfree_s(rose_neigh, sizeof(struct rose_neigh)); + kfree(rose_neigh->digipeat); + kfree(rose_neigh); return; } @@ -229,8 +228,8 @@ s->next = rose_neigh->next; restore_flags(flags); if (rose_neigh->digipeat != NULL) - kfree_s(rose_neigh->digipeat, sizeof(ax25_digi)); - kfree_s(rose_neigh, sizeof(struct rose_neigh)); + kfree(rose_neigh->digipeat); + kfree(rose_neigh); return; } @@ -251,7 +250,7 @@ if ((s = rose_route_list) == rose_route) { rose_route_list = rose_route->next; restore_flags(flags); - kfree_s(rose_route, sizeof(struct rose_route)); + kfree(rose_route); return; } @@ -259,7 +258,7 @@ if (s->next == rose_route) { s->next = rose_route->next; restore_flags(flags); - kfree_s(rose_route, sizeof(struct rose_route)); + kfree(rose_route); return; } @@ -372,7 +371,7 @@ struct rose_route *s, *rose_route = rose_route_list; while (rose_route != NULL) { - s = rose_route; + s = rose_route; rose_route = rose_route->next; if (s->neigh1->dev == dev || s->neigh2->dev == dev) @@ -397,7 +396,7 @@ } /* - * Find the first active Rose device, usually "rose0". + * Find the first active ROSE device, usually "rose0". */ struct device *rose_dev_first(void) { @@ -412,7 +411,7 @@ } /* - * Find the Rose device for the given address. + * Find the ROSE device for the given address. */ struct device *rose_dev_get(rose_address *addr) { @@ -426,22 +425,21 @@ } /* - * Find a neighbour given a Rose address. + * Find a neighbour given a ROSE address. */ struct rose_neigh *rose_get_neigh(rose_address *addr) { struct rose_node *node; int i; - for (node = rose_node_list; node != NULL; node = node->next) - if (rosecmpm(addr, &node->address, node->mask) == 0) - break; - - if (node == NULL) return NULL; - - for (i = 0; i < node->count; i++) - if (node->neighbour[i]->ftimer == 0) - return node->neighbour[i]; + for (node = rose_node_list; node != NULL; node = node->next) { + if (rosecmpm(addr, &node->address, node->mask) == 0) { + for (i = 0; i < node->count; i++) { + if (node->neighbour[i]->ftimer == 0) + return node->neighbour[i]; + } + } + } return NULL; } @@ -485,14 +483,54 @@ return 0; } +static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh) +{ + struct rose_route *rose_route, *s; + struct sk_buff *skb; + + rose_neigh->restarted = 0; + rose_neigh->t0timer = 0; + rose_neigh->ftimer = sysctl_rose_link_fail_timeout; + + rose_link_set_timer(rose_neigh); + + while ((skb = skb_dequeue(&rose_neigh->queue)) != NULL) + kfree_skb(skb, FREE_WRITE); + + rose_route = rose_route_list; + + while (rose_route != NULL) { + if ((rose_route->neigh1 == rose_neigh && rose_route->neigh2 == rose_neigh) || + (rose_route->neigh1 == rose_neigh && rose_route->neigh2 == NULL) || + (rose_route->neigh2 == rose_neigh && rose_route->neigh1 == NULL)) { + s = rose_route->next; + rose_remove_route(rose_route); + rose_route = s; + continue; + } + + if (rose_route->neigh1 == rose_neigh) { + rose_route->neigh1 = NULL; + rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, 0x0D); + } + + if (rose_route->neigh2 == rose_neigh) { + rose_route->neigh2 = NULL; + rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, 0x0D); + } + + rose_route = rose_route->next; + } +} + /* * A level 2 link has timed out, therefore it appears to be a poor link, - * then don't use that neighbour until it is reset. XXX others. + * then don't use that neighbour until it is reset. Blow away all through + * routes and connections using this route. */ void rose_link_failed(ax25_address *callsign, struct device *dev) { struct rose_neigh *rose_neigh; - struct sk_buff *skb; for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next) if (ax25cmp(&rose_neigh->callsign, callsign) == 0 && rose_neigh->dev == dev) @@ -500,33 +538,22 @@ if (rose_neigh == NULL) return; - rose_neigh->restarted = 0; - rose_neigh->t0timer = 0; - rose_neigh->ftimer = sysctl_rose_link_fail_timeout; - - rose_link_set_timer(rose_neigh); - - while ((skb = skb_dequeue(&rose_neigh->queue)) != NULL) - kfree_skb(skb, FREE_WRITE); + rose_del_route_by_neigh(rose_neigh); + rose_kill_by_neigh(rose_neigh); } /* - * A device has been "downed" remove its link status. XXX others. + * A device has been "downed" remove its link status. Blow away all + * through routes and connections that use this device. */ void rose_link_device_down(struct device *dev) { struct rose_neigh *rose_neigh; - struct sk_buff *skb; for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next) { if (rose_neigh->dev == dev) { - rose_neigh->restarted = 0; - rose_neigh->t0timer = 0; - rose_neigh->ftimer = 0; - del_timer(&rose_neigh->timer); - - while ((skb = skb_dequeue(&rose_neigh->queue)) != NULL) - kfree_skb(skb, FREE_WRITE); + rose_del_route_by_neigh(rose_neigh); + rose_kill_by_neigh(rose_neigh); } } } @@ -538,6 +565,7 @@ { struct rose_neigh *rose_neigh, *new_neigh; struct rose_route *rose_route; + struct rose_facilities facilities; rose_address *src_addr, *dest_addr; struct sock *sk; unsigned short frametype; @@ -597,29 +625,36 @@ /* * Route it to the next in line if we have an entry for it. */ - - /* - * We should check for the random number in the facilities - * here. XXX. - */ for (rose_route = rose_route_list; rose_route != NULL; rose_route = rose_route->next) { if (rose_route->lci1 == lci && rose_route->neigh1 == rose_neigh) { - skb->data[0] &= 0xF0; - skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F; - skb->data[1] = (rose_route->lci2 >> 0) & 0xFF; - rose_transmit_link(skb, rose_route->neigh2); - if (frametype == ROSE_CLEAR_CONFIRMATION) - rose_remove_route(rose_route); - return 1; + if (rose_route->neigh2 != NULL) { + skb->data[0] &= 0xF0; + skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F; + skb->data[1] = (rose_route->lci2 >> 0) & 0xFF; + rose_transmit_link(skb, rose_route->neigh2); + if (frametype == ROSE_CLEAR_CONFIRMATION) + rose_remove_route(rose_route); + return 1; + } else { + if (frametype == ROSE_CLEAR_CONFIRMATION) + rose_remove_route(rose_route); + return 0; + } } if (rose_route->lci2 == lci && rose_route->neigh2 == rose_neigh) { - skb->data[0] &= 0xF0; - skb->data[0] |= (rose_route->lci1 >> 8) & 0x0F; - skb->data[1] = (rose_route->lci1 >> 0) & 0xFF; - rose_transmit_link(skb, rose_route->neigh1); - if (frametype == ROSE_CLEAR_CONFIRMATION) - rose_remove_route(rose_route); - return 1; + if (rose_route->neigh1 != NULL) { + skb->data[0] &= 0xF0; + skb->data[0] |= (rose_route->lci1 >> 8) & 0x0F; + skb->data[1] = (rose_route->lci1 >> 0) & 0xFF; + rose_transmit_link(skb, rose_route->neigh1); + if (frametype == ROSE_CLEAR_CONFIRMATION) + rose_remove_route(rose_route); + return 1; + } else { + if (frametype == ROSE_CLEAR_CONFIRMATION) + rose_remove_route(rose_route); + return 0; + } } } @@ -631,20 +666,40 @@ if (frametype != ROSE_CALL_REQUEST) /* XXX */ return 0; + rose_parse_facilities(skb, &facilities); + + /* + * Check for routing loops. + */ + for (rose_route = rose_route_list; rose_route != NULL; rose_route = rose_route->next) { + if (rose_route->rand != 0x00 && rose_route->rand == facilities.rand) { + printk(KERN_DEBUG "ROSE: routing loop from %s\n", rose2asc(src_addr)); + printk(KERN_DEBUG "ROSE: to %s\n", rose2asc(dest_addr)); + rose_transmit_clear_request(rose_neigh, lci, 0x0D); + return 0; + } + } + if ((new_neigh = rose_get_neigh(dest_addr)) == NULL) { + printk(KERN_DEBUG "ROSE: no route to %s\n", rose2asc(dest_addr)); rose_transmit_clear_request(rose_neigh, lci, 0x0D); return 0; } - if ((rose_route = (struct rose_route *)kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) { + if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) { rose_transmit_clear_request(rose_neigh, lci, 0x0D); return 0; } - rose_route->lci1 = lci; - rose_route->neigh1 = rose_neigh; - rose_route->lci2 = rose_new_lci(new_neigh->dev); - rose_route->neigh2 = new_neigh; + rose_route->lci1 = lci; + rose_route->src_addr = *src_addr; + rose_route->dest_addr = *dest_addr; + rose_route->src_call = facilities.dest_call; + rose_route->dest_call = facilities.source_call; + rose_route->rand = facilities.rand; + rose_route->neigh1 = rose_neigh; + rose_route->lci2 = rose_new_lci(new_neigh->dev); + rose_route->neigh2 = new_neigh; save_flags(flags); cli(); rose_route->next = rose_route_list; @@ -759,17 +814,28 @@ cli(); - len += sprintf(buffer, "lci callsign dev <-> lci callsign dev\n"); + len += sprintf(buffer, "lci address callsign neigh <-> lci address callsign neigh\n"); for (rose_route = rose_route_list; rose_route != NULL; rose_route = rose_route->next) { - len += sprintf(buffer + len, "%3.3X %-9s %-4s ", - rose_route->lci1, - ax2asc(&rose_route->neigh1->callsign), - rose_route->neigh1->dev ? rose_route->neigh1->dev->name : "???"); - len += sprintf(buffer + len, "%3.3X %-9s %-4s\n", - rose_route->lci2, - ax2asc(&rose_route->neigh2->callsign), - rose_route->neigh2->dev ? rose_route->neigh2->dev->name : "???"); + if (rose_route->neigh1 != NULL) { + len += sprintf(buffer + len, "%3.3X %-10s %-9s %05d ", + rose_route->lci1, + rose2asc(&rose_route->src_addr), + ax2asc(&rose_route->src_call), + rose_route->neigh1->number); + } else { + len += sprintf(buffer + len, "000 * * 00000 "); + } + + if (rose_route->neigh2 != NULL) { + len += sprintf(buffer + len, "%3.3X %-10s %-9s %05d\n", + rose_route->lci2, + rose2asc(&rose_route->dest_addr), + ax2asc(&rose_route->dest_call), + rose_route->neigh2->number); + } else { + len += sprintf(buffer + len, "000 * * 00000\n"); + } pos = begin + len; @@ -795,7 +861,7 @@ #ifdef MODULE /* - * Release all memory associated with Rose routing structures. + * Release all memory associated with ROSE routing structures. */ void rose_rt_free(void) { @@ -811,7 +877,7 @@ } while (rose_node != NULL) { - t = rose_node; + t = rose_node; rose_node = rose_node->next; rose_remove_node(t); diff -u --recursive --new-file linux-2.1.30/net/rose/rose_subr.c linux/net/rose/rose_subr.c --- linux-2.1.30/net/rose/rose_subr.c Fri Jan 24 10:27:39 1997 +++ linux/net/rose/rose_subr.c Tue Mar 25 10:58:34 1997 @@ -1,8 +1,5 @@ /* - * Rose release 001 - * - * 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. + * ROSE release 002 * * This code REQUIRES 2.1.15 or higher/ NET3.038 * @@ -13,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * History - * Rose 001 Jonathan(G4KLX) Cloned from nr_subr.c + * ROSE 001 Jonathan(G4KLX) Cloned from nr_subr.c */ #include @@ -173,7 +170,7 @@ break; default: - printk(KERN_ERR "rose_write_internal: invalid frametype %02X\n", frametype); + printk(KERN_ERR "ROSE: rose_write_internal - invalid frametype %02X\n", frametype); kfree_skb(skb, FREE_WRITE); return; } @@ -227,7 +224,7 @@ return ROSE_ILLEGAL; } -static int rose_parse_national(unsigned char *p, rose_cb *rose, int len) +static int rose_parse_national(unsigned char *p, struct rose_facilities *facilities, int len) { unsigned char l, n = 0; @@ -241,7 +238,7 @@ case 0x40: if (*p == FAC_NATIONAL_RAND) - rose->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF); + facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF); p += 3; n += 3; len -= 3; @@ -256,12 +253,12 @@ case 0xC0: l = p[1]; if (*p == FAC_NATIONAL_DEST_DIGI) { - memcpy(&rose->source_digi, p + 2, AX25_ADDR_LEN); - rose->source_ndigis = 1; + memcpy(&facilities->source_digi, p + 2, AX25_ADDR_LEN); + facilities->source_ndigis = 1; } if (*p == FAC_NATIONAL_SRC_DIGI) { - memcpy(&rose->dest_digi, p + 2, AX25_ADDR_LEN); - rose->dest_ndigis = 1; + memcpy(&facilities->dest_digi, p + 2, AX25_ADDR_LEN); + facilities->dest_ndigis = 1; } p += l + 2; n += l + 2; @@ -273,7 +270,7 @@ return n; } -static int rose_parse_ccitt(unsigned char *p, rose_cb *rose, int len) +static int rose_parse_ccitt(unsigned char *p, struct rose_facilities *facilities, int len) { unsigned char l, n = 0; char callsign[11]; @@ -301,16 +298,16 @@ case 0xC0: l = p[1]; if (*p == FAC_CCITT_DEST_NSAP) { - memcpy(&rose->source_addr, p + 7, ROSE_ADDR_LEN); + memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN); memcpy(callsign, p + 12, l - 10); callsign[l - 10] = '\0'; - rose->source_call = *asc2ax(callsign); + facilities->source_call = *asc2ax(callsign); } if (*p == FAC_CCITT_SRC_NSAP) { - memcpy(&rose->dest_addr, p + 7, ROSE_ADDR_LEN); + memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN); memcpy(callsign, p + 12, l - 10); callsign[l - 10] = '\0'; - rose->dest_call = *asc2ax(callsign); + facilities->dest_call = *asc2ax(callsign); } p += l + 2; n += l + 2; @@ -322,12 +319,12 @@ return n; } -int rose_parse_facilities(struct sk_buff *skb, rose_cb *rose) +int rose_parse_facilities(struct sk_buff *skb, struct rose_facilities *facilities) { int facilities_len, len; unsigned char *p; - memset(rose, 0x00, sizeof(rose_cb)); + memset(facilities, 0x00, sizeof(struct rose_facilities)); len = (((skb->data[3] >> 4) & 0x0F) + 1) / 2; len += (((skb->data[3] >> 0) & 0x0F) + 1) / 2; @@ -346,19 +343,19 @@ switch (*p) { case FAC_NATIONAL: /* National */ - len = rose_parse_national(p + 1, rose, facilities_len - 1); + len = rose_parse_national(p + 1, facilities, facilities_len - 1); facilities_len -= len + 1; p += len + 1; break; case FAC_CCITT: /* CCITT */ - len = rose_parse_ccitt(p + 1, rose, facilities_len - 1); + len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); facilities_len -= len + 1; p += len + 1; break; default: - printk(KERN_DEBUG "rose_parse_facilities: unknown facilities family %02X\n", *p); + printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p); facilities_len--; p++; break; diff -u --recursive --new-file linux-2.1.30/net/rose/rose_timer.c linux/net/rose/rose_timer.c --- linux-2.1.30/net/rose/rose_timer.c Thu Mar 27 19:43:34 1997 +++ linux/net/rose/rose_timer.c Tue Mar 25 10:58:45 1997 @@ -1,8 +1,5 @@ /* - * Rose release 001 - * - * 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. + * ROSE release 002 * * This code REQUIRES 2.1.15 or higher/ NET3.038 * @@ -13,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * History - * Rose 001 Jonathan(G4KLX) Cloned from nr_timer.c + * ROSE 001 Jonathan(G4KLX) Cloned from nr_timer.c */ #include @@ -61,7 +58,7 @@ } /* - * Rose Timer + * ROSE Timer * * This routine is called every 100ms. Decrement timer by this * amount - if expired then process the event. diff -u --recursive --new-file linux-2.1.30/net/rose/sysctl_net_rose.c linux/net/rose/sysctl_net_rose.c --- linux-2.1.30/net/rose/sysctl_net_rose.c Fri Mar 7 14:48:21 1997 +++ linux/net/rose/sysctl_net_rose.c Tue Mar 25 10:58:54 1997 @@ -1,5 +1,5 @@ /* -*- linux-c -*- - * sysctl_net_rose.c: sysctl interface to net Rose subsystem. + * sysctl_net_rose.c: sysctl interface to net ROSE subsystem. * * Begun April 1, 1996, Mike Shaver. * Added /proc/sys/net/rose directory entry (empty =) ). [MS] diff -u --recursive --new-file linux-2.1.30/net/x25/Makefile linux/net/x25/Makefile --- linux-2.1.30/net/x25/Makefile Thu Dec 19 11:37:06 1996 +++ linux/net/x25/Makefile Sat Mar 8 21:08:38 1997 @@ -8,7 +8,8 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := x25.o -O_OBJS := af_x25.o sysctl_net_x25.o x25_dev.o x25_in.o x25_link.o x25_out.o x25_route.o x25_subr.o x25_timer.o +O_OBJS := af_x25.o sysctl_net_x25.o x25_dev.o x25_facilities.o x25_in.o \ + x25_link.o x25_out.o x25_route.o x25_subr.o x25_timer.o M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file linux-2.1.30/net/x25/af_x25.c linux/net/x25/af_x25.c --- linux-2.1.30/net/x25/af_x25.c Thu Mar 27 19:43:34 1997 +++ linux/net/x25/af_x25.c Tue Mar 25 10:40:07 1997 @@ -59,6 +59,8 @@ static struct proto_ops x25_proto_ops; +static x25_address null_x25_address = {" "}; + int x25_addr_ntoa(unsigned char *p, x25_address *called_addr, x25_address *calling_addr) { int called_len, calling_len; @@ -238,7 +240,9 @@ cli(); for (s = x25_list; s != NULL; s = s->next) { - if (strcmp(s->protinfo.x25->source_addr.x25_addr, addr->x25_addr) == 0 && s->state == TCP_LISTEN) { + if ((strcmp(addr->x25_addr, s->protinfo.x25->source_addr.x25_addr) == 0 || + strcmp(addr->x25_addr, null_x25_address.x25_addr) == 0) && + s->state == TCP_LISTEN) { restore_flags(flags); return s; } @@ -335,7 +339,7 @@ sk->timer.data = (unsigned long)sk; add_timer(&sk->timer); } else { - kfree_s(sk->protinfo.x25, sizeof(*sk->protinfo.x25)); + kfree(sk->protinfo.x25); sk_free(sk); MOD_DEC_USE_COUNT; } @@ -428,7 +432,7 @@ if ((sk = sk_alloc(GFP_ATOMIC)) == NULL) return NULL; - if ((x25 = (x25_cb *)kmalloc(sizeof(*x25), GFP_ATOMIC)) == NULL) { + if ((x25 = kmalloc(sizeof(*x25), GFP_ATOMIC)) == NULL) { sk_free(sk); return NULL; } @@ -599,7 +603,9 @@ x25_insert_socket(sk); sk->zapped = 0; + SOCK_DEBUG(sk, "x25_bind: socket is bound\n"); + return 0; } @@ -640,6 +646,9 @@ if (sk->zapped) /* Must bind first - autobinding does not work */ return -EINVAL; + if (strcmp(sk->protinfo.x25->source_addr.x25_addr, null_x25_address.x25_addr) == 0) + memset(&sk->protinfo.x25->source_addr, '\0', X25_ADDR_LEN); + sk->protinfo.x25->dest_addr = addr->sx25_addr; sk->protinfo.x25->lci = x25_new_lci(); @@ -660,7 +669,7 @@ cli(); /* To avoid races on the sleep */ /* - * A Connect Ack with Choke or timeout or failed routing will go to closed. + * A Clear Request or timeout or failed routing will go to closed. */ while (sk->state == TCP_SYN_SENT) { interruptible_sleep_on(sk->sleep); @@ -765,6 +774,7 @@ struct sock *make; x25_address source_addr, dest_addr; struct x25_facilities facilities; + int len; /* * Remove the LCI and frame type. @@ -785,16 +795,31 @@ /* * We can't accept the Call Request. */ - if (sk == NULL || sk->ack_backlog == sk->max_ack_backlog || (make = x25_make_new(sk)) == NULL) { + if (sk == NULL || sk->ack_backlog == sk->max_ack_backlog) { + x25_transmit_clear_request(neigh, lci, 0x01); + return 0; + } + + /* + * Try to reach a compromise on the requested facilities. + */ + if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1) { + x25_transmit_clear_request(neigh, lci, 0x01); + return 0; + } + + /* + * Try to create a new socket. + */ + if ((make = x25_make_new(sk)) == NULL) { x25_transmit_clear_request(neigh, lci, 0x01); return 0; } /* - * Parse the facilities, and remove them, leaving any Call User - * Data. + * Remove the facilities, leaving any Call User Data. */ - skb_pull(skb, x25_parse_facilities(skb, &facilities)); + skb_pull(skb, len); skb->sk = make; make->state = TCP_ESTABLISHED; @@ -803,11 +828,6 @@ make->protinfo.x25->dest_addr = dest_addr; make->protinfo.x25->source_addr = source_addr; make->protinfo.x25->neighbour = neigh; - - /* - * This implies that we accept all the incoming facilities - * values (if any). This needs fixing. XXX - */ make->protinfo.x25->facilities = facilities; x25_write_internal(make, X25_CALL_ACCEPTED); @@ -881,10 +901,12 @@ sx25.sx25_family = AF_X25; sx25.sx25_addr = sk->protinfo.x25->dest_addr; } + SOCK_DEBUG(sk, "x25_sendmsg: sendto: Addresses built.\n"); /* Build a packet */ SOCK_DEBUG(sk, "x25_sendmsg: sendto: building packet.\n"); + if ((msg->msg_flags & MSG_OOB) && len > 32) len = 32; @@ -899,8 +921,8 @@ * Put the data on the end */ SOCK_DEBUG(sk, "x25_sendmsg: Copying user data\n"); - skb->h.raw = skb_put(skb, len); - asmptr = skb->h.raw; + + asmptr = skb->h.raw = skb_put(skb, len); memcpy_fromiovec(asmptr, msg->msg_iov, len); @@ -917,6 +939,7 @@ * Push down the X.25 header */ SOCK_DEBUG(sk, "x25_sendmsg: Building X.25 Header.\n"); + if (msg->msg_flags & MSG_OOB) { if (sk->protinfo.x25->neighbour->extended) { asmptr = skb_push(skb, X25_STD_MIN_LEN); @@ -948,6 +971,7 @@ if (qbit) skb->data[0] |= X25_Q_BIT; } + SOCK_DEBUG(sk, "x25_sendmsg: Built header.\n"); SOCK_DEBUG(sk, "x25_sendmsg: Transmitting buffer\n"); @@ -1076,7 +1100,7 @@ case SIOCGSTAMP: if (sk != NULL) { - if (sk->stamp.tv_sec==0) + if (sk->stamp.tv_sec == 0) return -ENOENT; if ((err = verify_area(VERIFY_WRITE,(void *)arg,sizeof(struct timeval))) != 0) return err; @@ -1268,12 +1292,6 @@ 0, &proc_net_inode_operations, x25_get_info }; -static struct proc_dir_entry proc_net_x25_links = { - PROC_NET_X25_LINKS, 9, "x25_links", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - x25_link_get_info -}; static struct proc_dir_entry proc_net_x25_routes = { PROC_NET_X25_ROUTES, 10, "x25_routes", S_IFREG | S_IRUGO, 1, 0, 0, @@ -1297,7 +1315,6 @@ #ifdef CONFIG_PROC_FS proc_net_register(&proc_net_x25); - proc_net_register(&proc_net_x25_links); proc_net_register(&proc_net_x25_routes); #endif } @@ -1305,6 +1322,9 @@ #ifdef MODULE EXPORT_NO_SYMBOLS; +MODULE_AUTHOR("Jonathan Naylor "); +MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol"); + int init_module(void) { struct device *dev; @@ -1330,7 +1350,6 @@ #ifdef CONFIG_PROC_FS proc_net_unregister(PROC_NET_X25); - proc_net_unregister(PROC_NET_X25_LINKS); proc_net_unregister(PROC_NET_X25_ROUTES); #endif diff -u --recursive --new-file linux-2.1.30/net/x25/x25_facilities.c linux/net/x25/x25_facilities.c --- linux-2.1.30/net/x25/x25_facilities.c Thu Jan 1 01:00:00 1970 +++ linux/net/x25/x25_facilities.c Tue Mar 11 17:18:07 1997 @@ -0,0 +1,203 @@ +/* + * X.25 Packet Layer release 001 + * + * 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. + * + * This code REQUIRES 2.1.15 or higher + * + * This module: + * This module is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * History + * X.25 001 Split from x25_subr.c + */ + +#include +#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Parse a set of facilities into the facilities structure. Unrecognised + * facilities are written to the debug log file. + */ +int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities) +{ + unsigned int len; + unsigned char *p = skb->data; + + len = *p++; + + while (len > 0) { + switch (*p & X25_FAC_CLASS_MASK) { + case X25_FAC_CLASS_A: + switch (*p) { + case X25_FAC_REVERSE: + facilities->reverse = (p[1] & 0x01); + break; + case X25_FAC_THROUGHPUT: + facilities->throughput = p[1]; + break; + default: + printk(KERN_DEBUG "X.25: unknown facility %02X, value %02X\n", p[0], p[1]); + break; + } + p += 2; + len -= 2; + break; + + case X25_FAC_CLASS_B: + switch (*p) { + case X25_FAC_PACKET_SIZE: + facilities->pacsize_in = p[1]; + facilities->pacsize_out = p[2]; + break; + case X25_FAC_WINDOW_SIZE: + facilities->winsize_in = p[1]; + facilities->winsize_out = p[2]; + break; + default: + printk(KERN_DEBUG "X.25: unknown facility %02X, values %02X, %02X\n", p[0], p[1], p[2]); + break; + } + p += 3; + len -= 3; + break; + + case X25_FAC_CLASS_C: + printk(KERN_DEBUG "X.25: unknown facility %02X, values %02X, %02X, %02X\n", p[0], p[1], p[2], p[3]); + p += 4; + len -= 4; + break; + + case X25_FAC_CLASS_D: + printk(KERN_DEBUG "X.25: unknown facility %02X, length %d, values %02X, %02X, %02X, %02X\n", p[0], p[1], p[2], p[3], p[4], p[5]); + p += p[1] + 2; + len -= p[1] + 2; + break; + } + } + + return p - skb->data; +} + +/* + * Create a set of facilities. + */ +int x25_create_facilities(unsigned char *buffer, struct x25_facilities *facilities) +{ + unsigned char *p = buffer + 1; + int len; + + if (facilities->reverse != 0) { + *p++ = X25_FAC_REVERSE; + *p++ = (facilities->reverse) ? 0x01 : 0x00; + } + + if (facilities->throughput != 0) { + *p++ = X25_FAC_THROUGHPUT; + *p++ = facilities->throughput; + } + + if (facilities->pacsize_in != 0 || facilities->pacsize_out != 0) { + *p++ = X25_FAC_PACKET_SIZE; + *p++ = (facilities->pacsize_in == 0) ? facilities->pacsize_out : facilities->pacsize_in; + *p++ = (facilities->pacsize_out == 0) ? facilities->pacsize_in : facilities->pacsize_out; + } + + if (facilities->winsize_in != 0 || facilities->winsize_out != 0) { + *p++ = X25_FAC_WINDOW_SIZE; + *p++ = (facilities->winsize_in == 0) ? facilities->winsize_out : facilities->winsize_in; + *p++ = (facilities->winsize_out == 0) ? facilities->winsize_in : facilities->winsize_out; + } + + len = p - buffer; + buffer[0] = len - 1; + + return len; +} + +/* + * Try to reach a compromise on a set of facilities. + * + * The only real problem is with reverse charging. + */ +int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, struct x25_facilities *new) +{ + struct x25_facilities *ours; + struct x25_facilities theirs; + int len; + + memset(&theirs, 0x00, sizeof(struct x25_facilities)); + + ours = &sk->protinfo.x25->facilities; + + *new = *ours; + + len = x25_parse_facilities(skb, &theirs); + + /* + * They want reverse charging, we won't accept it. + */ + if (theirs.reverse != 0 && ours->reverse == 0) { + SOCK_DEBUG(sk, "X.25: rejecting reverse charging request"); + return -1; + } + + new->reverse = theirs.reverse; + + if (theirs.throughput != 0) { + if (theirs.throughput < ours->throughput) { + SOCK_DEBUG(sk, "X.25: throughput negotiated down"); + new->throughput = theirs.throughput; + } + } + + if (theirs.pacsize_in != 0 && theirs.pacsize_out != 0) { + if (theirs.pacsize_in < ours->pacsize_in) { + SOCK_DEBUG(sk, "X.25: packet size inwards negotiated down"); + new->pacsize_in = theirs.pacsize_in; + } + if (theirs.pacsize_out < ours->pacsize_out) { + SOCK_DEBUG(sk, "X.25: packet size outwards negotiated down"); + new->pacsize_out = theirs.pacsize_out; + } + } + + if (theirs.winsize_in != 0 && theirs.winsize_out != 0) { + if (theirs.winsize_in < ours->winsize_in) { + SOCK_DEBUG(sk, "X.25: window size inwards negotiated down"); + new->winsize_in = theirs.winsize_in; + } + if (theirs.winsize_out < ours->winsize_out) { + SOCK_DEBUG(sk, "X.25: window size outwards negotiated down"); + new->winsize_out = theirs.winsize_out; + } + } + + return len; +} + +#endif diff -u --recursive --new-file linux-2.1.30/net/x25/x25_in.c linux/net/x25/x25_in.c --- linux-2.1.30/net/x25/x25_in.c Fri Mar 7 14:49:18 1997 +++ linux/net/x25/x25_in.c Tue Mar 11 17:16:33 1997 @@ -84,7 +84,6 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype) { x25_address source_addr, dest_addr; - struct x25_facilities facilities; switch (frametype) { @@ -102,9 +101,8 @@ */ skb_pull(skb, X25_STD_MIN_LEN); skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr)); - skb_pull(skb, x25_parse_facilities(skb, &facilities)); + skb_pull(skb, x25_parse_facilities(skb, &sk->protinfo.x25->facilities)); /* - * Facilities XXX * Copy any Call User Data. */ if (skb->len >= 0) { @@ -128,7 +126,6 @@ break; default: - printk(KERN_WARNING "x25: unknown %02X in state 1\n", frametype); break; } @@ -158,7 +155,6 @@ break; default: - printk(KERN_WARNING "x25: unknown %02X in state 2\n", frametype); break; } @@ -334,7 +330,6 @@ break; default: - printk(KERN_WARNING "x25: unknown %02X in state 4\n", frametype); break; } diff -u --recursive --new-file linux-2.1.30/net/x25/x25_link.c linux/net/x25/x25_link.c --- linux-2.1.30/net/x25/x25_link.c Thu Mar 27 19:43:34 1997 +++ linux/net/x25/x25_link.c Thu Mar 27 20:16:53 1997 @@ -240,8 +240,10 @@ void x25_transmit_link(struct sk_buff *skb, struct x25_neigh *neigh) { - if (call_fw_firewall(PF_X25, skb->dev, skb->data, NULL,&skb) != FW_ACCEPT) + if (call_fw_firewall(PF_X25, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT) { + kfree_skb(skb, FREE_WRITE); return; + } switch (neigh->state) { case X25_LINK_STATE_0: @@ -294,7 +296,7 @@ struct x25_neigh *x25_neigh; unsigned long flags; - if ((x25_neigh = (struct x25_neigh *)kmalloc(sizeof(*x25_neigh), GFP_ATOMIC)) == NULL) + if ((x25_neigh = kmalloc(sizeof(*x25_neigh), GFP_ATOMIC)) == NULL) return; skb_queue_head_init(&x25_neigh->queue); @@ -329,7 +331,7 @@ if ((s = x25_neigh_list) == x25_neigh) { x25_neigh_list = x25_neigh->next; restore_flags(flags); - kfree_s(x25_neigh, sizeof(struct x25_neigh)); + kfree(x25_neigh); return; } @@ -337,7 +339,7 @@ if (s->next == x25_neigh) { s->next = x25_neigh->next; restore_flags(flags); - kfree_s(x25_neigh, sizeof(struct x25_neigh)); + kfree(x25_neigh); return; } @@ -419,46 +421,6 @@ return 0; } - -int x25_link_get_info(char *buffer, char **start, off_t offset, int length, int dummy) -{ - struct x25_neigh *x25_neigh; - int len = 0; - off_t pos = 0; - off_t begin = 0; - - cli(); - - len += sprintf(buffer, "device st t20 ext\n"); - - for (x25_neigh = x25_neigh_list; x25_neigh != NULL; x25_neigh = x25_neigh->next) { - len += sprintf(buffer + len, "%-6s %2d %3d/%03d %d\n", - x25_neigh->dev->name, - x25_neigh->state, - x25_neigh->t20timer / X25_SLOWHZ, - x25_neigh->t20 / X25_SLOWHZ, - x25_neigh->extended); - - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - - if (pos > offset + length) - break; - } - - sti(); - - *start = buffer + (offset - begin); - len -= (offset - begin); - - if (len > length) len = length; - - return len; -} #ifdef MODULE diff -u --recursive --new-file linux-2.1.30/net/x25/x25_route.c linux/net/x25/x25_route.c --- linux-2.1.30/net/x25/x25_route.c Fri Jan 24 10:27:40 1997 +++ linux/net/x25/x25_route.c Sun Mar 16 11:09:50 1997 @@ -59,7 +59,7 @@ if (memcmp(&x25_route->address, address, sigdigits) == 0 && x25_route->sigdigits == sigdigits) return -EINVAL; - if ((x25_route = (struct x25_route *)kmalloc(sizeof(*x25_route), GFP_ATOMIC)) == NULL) + if ((x25_route = kmalloc(sizeof(*x25_route), GFP_ATOMIC)) == NULL) return -ENOMEM; strcpy(x25_route->address.x25_addr, "000000000000000"); @@ -87,7 +87,7 @@ if ((s = x25_route_list) == x25_route) { x25_route_list = x25_route->next; restore_flags(flags); - kfree_s(x25_route, sizeof(struct x25_route)); + kfree(x25_route); return; } @@ -95,7 +95,7 @@ if (s->next == x25_route) { s->next = x25_route->next; restore_flags(flags); - kfree_s(x25_route, sizeof(struct x25_route)); + kfree(x25_route); return; } diff -u --recursive --new-file linux-2.1.30/net/x25/x25_subr.c linux/net/x25/x25_subr.c --- linux-2.1.30/net/x25/x25_subr.c Fri Jan 24 10:27:40 1997 +++ linux/net/x25/x25_subr.c Sat Mar 8 21:07:34 1997 @@ -281,106 +281,4 @@ return X25_ILLEGAL; } -/* - * Parse a set of facilities into the facilities structure. Unrecognised - * facilities are written to the debug log file. - */ -int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities) -{ - unsigned int len; - unsigned char *p = skb->data; - - memset(facilities, 0x00, sizeof(struct x25_facilities)); - - len = *p++; - - while (len > 0) { - switch (*p & X25_FAC_CLASS_MASK) { - case X25_FAC_CLASS_A: - switch (*p) { - case X25_FAC_REVERSE: - facilities->reverse = (p[1] & 0x01); - break; - case X25_FAC_THROUGHPUT: - facilities->throughput = p[1]; - break; - default: - printk(KERN_DEBUG "X.25: unknown facility %02X, value %02X\n", p[0], p[1]); - break; - } - p += 2; - len -= 2; - break; - - case X25_FAC_CLASS_B: - switch (*p) { - case X25_FAC_PACKET_SIZE: - facilities->pacsize_in = p[1]; - facilities->pacsize_out = p[2]; - break; - case X25_FAC_WINDOW_SIZE: - facilities->winsize_in = p[1]; - facilities->winsize_out = p[2]; - break; - default: - printk(KERN_DEBUG "X.25: unknown facility %02X, values %02X, %02X\n", p[0], p[1], p[2]); - break; - } - p += 3; - len -= 3; - break; - - case X25_FAC_CLASS_C: - printk(KERN_DEBUG "X.25: unknown facility %02X, values %02X, %02X, %02X\n", p[0], p[1], p[2], p[3]); - p += 4; - len -= 4; - break; - - case X25_FAC_CLASS_D: - printk(KERN_DEBUG "X.25: unknown facility %02X, length %d, values %02X, %02X, %02X, %02X\n", p[0], p[1], p[2], p[3], p[4], p[5]); - p += p[1] + 2; - len -= p[1] + 2; - break; - } - } - - return p - skb->data; -} - -/* - * Create a set of facilities. - */ -int x25_create_facilities(unsigned char *buffer, struct x25_facilities *facilities) -{ - unsigned char *p = buffer + 1; - int len; - - if (facilities->reverse != 0) { - *p++ = X25_FAC_REVERSE; - *p++ = (facilities->reverse) ? 0x01 : 0x00; - } - - if (facilities->throughput != 0) { - *p++ = X25_FAC_THROUGHPUT; - *p++ = facilities->throughput; - } - - if (facilities->pacsize_in != 0 || facilities->pacsize_out != 0) { - *p++ = X25_FAC_PACKET_SIZE; - *p++ = (facilities->pacsize_in == 0) ? facilities->pacsize_out : facilities->pacsize_in; - *p++ = (facilities->pacsize_out == 0) ? facilities->pacsize_in : facilities->pacsize_out; - } - - if (facilities->winsize_in != 0 || facilities->winsize_out != 0) { - *p++ = X25_FAC_WINDOW_SIZE; - *p++ = (facilities->winsize_in == 0) ? facilities->winsize_out : facilities->winsize_in; - *p++ = (facilities->winsize_out == 0) ? facilities->winsize_in : facilities->winsize_out; - } - - len = p - buffer; - buffer[0] = len - 1; - - return len; -} - #endif