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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [ax25/] [ax25_ip.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * This program is free software; you can redistribute it and/or modify
3
 * it under the terms of the GNU General Public License as published by
4
 * the Free Software Foundation; either version 2 of the License, or
5
 * (at your option) any later version.
6
 *
7
 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
8
 */
9
#include <linux/errno.h>
10
#include <linux/types.h>
11
#include <linux/socket.h>
12
#include <linux/in.h>
13
#include <linux/kernel.h>
14
#include <linux/module.h>
15
#include <linux/timer.h>
16
#include <linux/string.h>
17
#include <linux/sockios.h>
18
#include <linux/net.h>
19
#include <net/ax25.h>
20
#include <linux/inet.h>
21
#include <linux/netdevice.h>
22
#include <linux/if_arp.h>
23
#include <linux/skbuff.h>
24
#include <net/sock.h>
25
#include <asm/uaccess.h>
26
#include <asm/system.h>
27
#include <linux/fcntl.h>
28
#include <linux/termios.h>      /* For TIOCINQ/OUTQ */
29
#include <linux/mm.h>
30
#include <linux/interrupt.h>
31
#include <linux/notifier.h>
32
#include <linux/proc_fs.h>
33
#include <linux/stat.h>
34
#include <linux/netfilter.h>
35
#include <linux/sysctl.h>
36
#include <net/ip.h>
37
#include <net/arp.h>
38
 
39
/*
40
 *      IP over AX.25 encapsulation.
41
 */
42
 
43
/*
44
 *      Shove an AX.25 UI header on an IP packet and handle ARP
45
 */
46
 
47
#ifdef CONFIG_INET
48
 
49
int ax25_hard_header(struct sk_buff *skb, struct net_device *dev,
50
                     unsigned short type, const void *daddr,
51
                     const void *saddr, unsigned len)
52
{
53
        unsigned char *buff;
54
 
55
        /* they sometimes come back to us... */
56
        if (type == ETH_P_AX25)
57
                return 0;
58
 
59
        /* header is an AX.25 UI frame from us to them */
60
        buff = skb_push(skb, AX25_HEADER_LEN);
61
        *buff++ = 0x00; /* KISS DATA */
62
 
63
        if (daddr != NULL)
64
                memcpy(buff, daddr, dev->addr_len);     /* Address specified */
65
 
66
        buff[6] &= ~AX25_CBIT;
67
        buff[6] &= ~AX25_EBIT;
68
        buff[6] |= AX25_SSSID_SPARE;
69
        buff    += AX25_ADDR_LEN;
70
 
71
        if (saddr != NULL)
72
                memcpy(buff, saddr, dev->addr_len);
73
        else
74
                memcpy(buff, dev->dev_addr, dev->addr_len);
75
 
76
        buff[6] &= ~AX25_CBIT;
77
        buff[6] |= AX25_EBIT;
78
        buff[6] |= AX25_SSSID_SPARE;
79
        buff    += AX25_ADDR_LEN;
80
 
81
        *buff++  = AX25_UI;     /* UI */
82
 
83
        /* Append a suitable AX.25 PID */
84
        switch (type) {
85
        case ETH_P_IP:
86
                *buff++ = AX25_P_IP;
87
                break;
88
        case ETH_P_ARP:
89
                *buff++ = AX25_P_ARP;
90
                break;
91
        default:
92
                printk(KERN_ERR "AX.25: ax25_hard_header - wrong protocol type 0x%2.2x\n", type);
93
                *buff++ = 0;
94
                break;
95
        }
96
 
97
        if (daddr != NULL)
98
                return AX25_HEADER_LEN;
99
 
100
        return -AX25_HEADER_LEN;        /* Unfinished header */
101
}
102
 
103
int ax25_rebuild_header(struct sk_buff *skb)
104
{
105
        struct sk_buff *ourskb;
106
        unsigned char *bp  = skb->data;
107
        ax25_route *route;
108
        struct net_device *dev = NULL;
109
        ax25_address *src, *dst;
110
        ax25_digi *digipeat = NULL;
111
        ax25_dev *ax25_dev;
112
        ax25_cb *ax25;
113
        char ip_mode = ' ';
114
 
115
        dst = (ax25_address *)(bp + 1);
116
        src = (ax25_address *)(bp + 8);
117
 
118
        if (arp_find(bp + 1, skb))
119
                return 1;
120
 
121
        route = ax25_get_route(dst, NULL);
122
        if (route) {
123
                digipeat = route->digipeat;
124
                dev = route->dev;
125
                ip_mode = route->ip_mode;
126
        }
127
 
128
        if (dev == NULL)
129
                dev = skb->dev;
130
 
131
        if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) {
132
                goto put;
133
        }
134
 
135
        if (bp[16] == AX25_P_IP) {
136
                if (ip_mode == 'V' || (ip_mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) {
137
                        /*
138
                         *      We copy the buffer and release the original thereby
139
                         *      keeping it straight
140
                         *
141
                         *      Note: we report 1 back so the caller will
142
                         *      not feed the frame direct to the physical device
143
                         *      We don't want that to happen. (It won't be upset
144
                         *      as we have pulled the frame from the queue by
145
                         *      freeing it).
146
                         *
147
                         *      NB: TCP modifies buffers that are still
148
                         *      on a device queue, thus we use skb_copy()
149
                         *      instead of using skb_clone() unless this
150
                         *      gets fixed.
151
                         */
152
 
153
                        ax25_address src_c;
154
                        ax25_address dst_c;
155
 
156
                        if ((ourskb = skb_copy(skb, GFP_ATOMIC)) == NULL) {
157
                                kfree_skb(skb);
158
                                goto put;
159
                        }
160
 
161
                        if (skb->sk != NULL)
162
                                skb_set_owner_w(ourskb, skb->sk);
163
 
164
                        kfree_skb(skb);
165
                        /* dl9sau: bugfix
166
                         * after kfree_skb(), dst and src which were pointer
167
                         * to bp which is part of skb->data would not be valid
168
                         * anymore hope that after skb_pull(ourskb, ..) our
169
                         * dsc_c and src_c will not become invalid
170
                         */
171
                        bp  = ourskb->data;
172
                        dst_c = *(ax25_address *)(bp + 1);
173
                        src_c = *(ax25_address *)(bp + 8);
174
 
175
                        skb_pull(ourskb, AX25_HEADER_LEN - 1);  /* Keep PID */
176
                        skb_reset_network_header(ourskb);
177
 
178
                        ax25=ax25_send_frame(
179
                            ourskb,
180
                            ax25_dev->values[AX25_VALUES_PACLEN],
181
                            &src_c,
182
                            &dst_c, digipeat, dev);
183
                        if (ax25) {
184
                                ax25_cb_put(ax25);
185
                        }
186
                        goto put;
187
                }
188
        }
189
 
190
        bp[7]  &= ~AX25_CBIT;
191
        bp[7]  &= ~AX25_EBIT;
192
        bp[7]  |= AX25_SSSID_SPARE;
193
 
194
        bp[14] &= ~AX25_CBIT;
195
        bp[14] |= AX25_EBIT;
196
        bp[14] |= AX25_SSSID_SPARE;
197
 
198
        skb_pull(skb, AX25_KISS_HEADER_LEN);
199
 
200
        if (digipeat != NULL) {
201
                if ((ourskb = ax25_rt_build_path(skb, src, dst, route->digipeat)) == NULL) {
202
                        kfree_skb(skb);
203
                        goto put;
204
                }
205
 
206
                skb = ourskb;
207
        }
208
 
209
        ax25_queue_xmit(skb, dev);
210
 
211
put:
212
        if (route)
213
                ax25_put_route(route);
214
 
215
        return 1;
216
}
217
 
218
#else   /* INET */
219
 
220
int ax25_hard_header(struct sk_buff *skb, struct net_device *dev,
221
                     unsigned short type, const void *daddr,
222
                     const void *saddr, unsigned len)
223
{
224
        return -AX25_HEADER_LEN;
225
}
226
 
227
int ax25_rebuild_header(struct sk_buff *skb)
228
{
229
        return 1;
230
}
231
 
232
#endif
233
 
234
const struct header_ops ax25_header_ops = {
235
        .create = ax25_hard_header,
236
        .rebuild = ax25_rebuild_header,
237
};
238
 
239
EXPORT_SYMBOL(ax25_hard_header);
240
EXPORT_SYMBOL(ax25_rebuild_header);
241
EXPORT_SYMBOL(ax25_header_ops);
242
 

powered by: WebSVN 2.1.0

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