OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [netrom/] [nr_dev.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      NET/ROM release 007
3
 *
4
 *      This code REQUIRES 2.1.15 or higher/ NET3.038
5
 *
6
 *      This module:
7
 *              This module is free software; you can redistribute it and/or
8
 *              modify it under the terms of the GNU General Public License
9
 *              as published by the Free Software Foundation; either version
10
 *              2 of the License, or (at your option) any later version.
11
 *
12
 *      History
13
 *      NET/ROM 001     Jonathan(G4KLX) Cloned from loopback.c
14
 *      NET/ROM 002     Steve Whitehouse(GW7RRM) fixed the set_mac_address
15
 *      NET/ROM 003     Jonathan(G4KLX) Put nr_rebuild_header into line with
16
 *                                      ax25_rebuild_header
17
 *      NET/ROM 004     Jonathan(G4KLX) Callsign registration with AX.25.
18
 *      NET/ROM 006     Hans(PE1AYX)    Fixed interface to IP layer.
19
 */
20
 
21
#include <linux/config.h>
22
#include <linux/module.h>
23
#include <linux/proc_fs.h>
24
#include <linux/kernel.h>
25
#include <linux/sched.h>
26
#include <linux/interrupt.h>
27
#include <linux/fs.h>
28
#include <linux/types.h>
29
#include <linux/sysctl.h>
30
#include <linux/string.h>
31
#include <linux/socket.h>
32
#include <linux/errno.h>
33
#include <linux/fcntl.h>
34
#include <linux/in.h>
35
#include <linux/if_ether.h>     /* For the statistics structure. */
36
 
37
#include <asm/system.h>
38
#include <asm/uaccess.h>
39
#include <asm/io.h>
40
 
41
#include <linux/inet.h>
42
#include <linux/netdevice.h>
43
#include <linux/etherdevice.h>
44
#include <linux/if_arp.h>
45
#include <linux/skbuff.h>
46
 
47
#include <net/ip.h>
48
#include <net/arp.h>
49
 
50
#include <net/ax25.h>
51
#include <net/netrom.h>
52
 
53
#ifdef CONFIG_INET
54
 
55
/*
56
 *      Only allow IP over NET/ROM frames through if the netrom device is up.
57
 */
58
 
59
int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
60
{
61
        struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
62
 
63
        if (!netif_running(dev)) {
64
                stats->rx_errors++;
65
                return 0;
66
        }
67
 
68
        stats->rx_packets++;
69
        stats->rx_bytes += skb->len;
70
 
71
        skb->protocol = htons(ETH_P_IP);
72
 
73
        /* Spoof incoming device */
74
        skb->dev      = dev;
75
        skb->h.raw    = skb->data;
76
        skb->nh.raw   = skb->data;
77
        skb->pkt_type = PACKET_HOST;
78
 
79
        ip_rcv(skb, skb->dev, NULL);
80
 
81
        return 1;
82
}
83
 
84
 
85
static int nr_rebuild_header(struct sk_buff *skb)
86
{
87
        struct net_device *dev = skb->dev;
88
        struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
89
        struct sk_buff *skbn;
90
        unsigned char *bp = skb->data;
91
        int len;
92
 
93
        if (arp_find(bp + 7, skb)) {
94
                return 1;
95
        }
96
 
97
        bp[6] &= ~AX25_CBIT;
98
        bp[6] &= ~AX25_EBIT;
99
        bp[6] |= AX25_SSSID_SPARE;
100
        bp    += AX25_ADDR_LEN;
101
 
102
        bp[6] &= ~AX25_CBIT;
103
        bp[6] |= AX25_EBIT;
104
        bp[6] |= AX25_SSSID_SPARE;
105
 
106
        if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
107
                kfree_skb(skb);
108
                return 1;
109
        }
110
 
111
        if (skb->sk != NULL)
112
                skb_set_owner_w(skbn, skb->sk);
113
 
114
        kfree_skb(skb);
115
 
116
        len = skbn->len;
117
 
118
        if (!nr_route_frame(skbn, NULL)) {
119
                kfree_skb(skbn);
120
                stats->tx_errors++;
121
        }
122
 
123
        stats->tx_packets++;
124
        stats->tx_bytes += len;
125
 
126
        return 1;
127
}
128
 
129
#else
130
 
131
static int nr_rebuild_header(struct sk_buff *skb)
132
{
133
        return 1;
134
}
135
 
136
#endif
137
 
138
static int nr_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
139
        void *daddr, void *saddr, unsigned len)
140
{
141
        unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
142
 
143
        memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len);
144
        buff[6] &= ~AX25_CBIT;
145
        buff[6] &= ~AX25_EBIT;
146
        buff[6] |= AX25_SSSID_SPARE;
147
        buff    += AX25_ADDR_LEN;
148
 
149
        if (daddr != NULL)
150
                memcpy(buff, daddr, dev->addr_len);
151
        buff[6] &= ~AX25_CBIT;
152
        buff[6] |= AX25_EBIT;
153
        buff[6] |= AX25_SSSID_SPARE;
154
        buff    += AX25_ADDR_LEN;
155
 
156
        *buff++ = sysctl_netrom_network_ttl_initialiser;
157
 
158
        *buff++ = NR_PROTO_IP;
159
        *buff++ = NR_PROTO_IP;
160
        *buff++ = 0;
161
        *buff++ = 0;
162
        *buff++ = NR_PROTOEXT;
163
 
164
        if (daddr != NULL)
165
                return 37;
166
 
167
        return -37;
168
}
169
 
170
static int nr_set_mac_address(struct net_device *dev, void *addr)
171
{
172
        struct sockaddr *sa = addr;
173
 
174
        ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
175
 
176
        memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
177
 
178
        ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
179
 
180
        return 0;
181
}
182
 
183
static int nr_open(struct net_device *dev)
184
{
185
        MOD_INC_USE_COUNT;
186
        netif_start_queue(dev);
187
        ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
188
        return 0;
189
}
190
 
191
static int nr_close(struct net_device *dev)
192
{
193
        netif_stop_queue(dev);
194
        ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
195
        MOD_DEC_USE_COUNT;
196
        return 0;
197
}
198
 
199
static int nr_xmit(struct sk_buff *skb, struct net_device *dev)
200
{
201
        struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
202
        dev_kfree_skb(skb);
203
        stats->tx_errors++;
204
        return 0;
205
}
206
 
207
static struct net_device_stats *nr_get_stats(struct net_device *dev)
208
{
209
        return (struct net_device_stats *)dev->priv;
210
}
211
 
212
int nr_init(struct net_device *dev)
213
{
214
        dev->mtu                = NR_MAX_PACKET_SIZE;
215
        dev->hard_start_xmit    = nr_xmit;
216
        dev->open               = nr_open;
217
        dev->stop               = nr_close;
218
 
219
        dev->hard_header        = nr_header;
220
        dev->hard_header_len    = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
221
        dev->addr_len           = AX25_ADDR_LEN;
222
        dev->type               = ARPHRD_NETROM;
223
        dev->rebuild_header     = nr_rebuild_header;
224
        dev->set_mac_address    = nr_set_mac_address;
225
 
226
        /* New-style flags. */
227
        dev->flags              = 0;
228
 
229
        if ((dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL)) == NULL)
230
                return -ENOMEM;
231
 
232
        memset(dev->priv, 0, sizeof(struct net_device_stats));
233
 
234
        dev->get_stats = nr_get_stats;
235
 
236
        return 0;
237
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.