Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
be9ca388
Commit
be9ca388
authored
Aug 03, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/home/acme/BK/appletalk-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents
43bd3834
f1bbf6ab
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
397 additions
and
357 deletions
+397
-357
include/linux/atalk.h
include/linux/atalk.h
+94
-74
net/appletalk/aarp.c
net/appletalk/aarp.c
+100
-101
net/appletalk/ddp.c
net/appletalk/ddp.c
+203
-182
No files found.
include/linux/atalk.h
View file @
be9ca388
#ifndef __LINUX_ATALK_H__
#define __LINUX_ATALK_H__
/*
*
AppleTalk networking structures
*
AppleTalk networking structures
*
*
The following are directly referenced from the University Of Michigan
*
netatalk for compatibility reasons.
*
The following are directly referenced from the University Of Michigan
*
netatalk for compatibility reasons.
*/
#ifndef __LINUX_ATALK_H__
#define __LINUX_ATALK_H__
#define ATPORT_FIRST 1
#define ATPORT_RESERVED 128
#define ATPORT_LAST 254
/* 254 is only legal on localtalk */
#define ATPORT_LAST 254
/* 254 is only legal on localtalk */
#define ATADDR_ANYNET (__u16)0
#define ATADDR_ANYNODE (__u8)0
#define ATADDR_ANYPORT (__u8)0
#define ATADDR_BCAST (__u8)255
#define DDP_MAXSZ 587
#define DDP_MAXHOPS 15
/* 4 bits of hop counter */
#define DDP_MAXHOPS 15
/* 4 bits of hop counter */
#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0)
struct
at_addr
{
struct
atalk_addr
{
__u16
s_net
;
__u8
s_node
;
};
struct
sockaddr_at
{
sa_family_t
sat_family
;
__u8
sat_port
;
struct
at_addr
sat_addr
;
char
sat_zero
[
8
];
struct
sockaddr_at
{
sa_family_t
sat_family
;
__u8
sat_port
;
struct
atalk_addr
sat_addr
;
char
sat_zero
[
8
];
};
struct
netrange
{
struct
atalk_netrange
{
__u8
nr_phase
;
__u16
nr_firstnet
;
__u16
nr_lastnet
;
};
struct
atalk_route
{
struct
net_device
*
dev
;
struct
at_addr
target
;
struct
at_addr
gateway
;
int
flags
;
struct
atalk_route
{
struct
net_device
*
dev
;
struct
atalk_addr
target
;
struct
atalk_addr
gateway
;
int
flags
;
struct
atalk_route
*
next
;
};
struct
atalk_iface
{
struct
net_device
*
dev
;
struct
at_addr
address
;
/* Our address */
int
status
;
/* What are we doing? */
/**
* struct atalk_iface - AppleTalk Interface
* @dev - Network device associated with this interface
* @address - Our address
* @status - What are we doing?
* @nets - Associated direct netrange
* @next - next element in the list of interfaces
*/
struct
atalk_iface
{
struct
net_device
*
dev
;
struct
atalk_addr
address
;
int
status
;
#define ATIF_PROBE 1
/* Probing for an address */
#define ATIF_PROBE_FAIL 2
/* Probe collided */
struct
netrange
nets
;
/* Associated direct netrange */
struct
atalk_iface
*
next
;
struct
atalk_netrange
nets
;
struct
atalk_iface
*
next
;
};
struct
atalk_sock
{
unsigned
short
dest_net
;
unsigned
short
src_net
;
unsigned
char
dest_node
;
unsigned
char
src_node
;
unsigned
char
dest_port
;
unsigned
char
src_port
;
struct
atalk_sock
{
unsigned
short
dest_net
;
unsigned
short
src_net
;
unsigned
char
dest_node
;
unsigned
char
src_node
;
unsigned
char
dest_port
;
unsigned
char
src_port
;
};
#ifdef __KERNEL__
#include <asm/byteorder.h>
struct
ddpehdr
{
struct
ddpehdr
{
#ifdef __LITTLE_ENDIAN_BITFIELD
__u16
deh_len
:
10
,
deh_hops
:
4
,
deh_pad
:
2
;
__u16
deh_len
:
10
,
deh_hops:
4
,
deh_pad:
2
;
#else
__u16
deh_pad
:
2
,
deh_hops
:
4
,
deh_len
:
10
;
__u16
deh_pad
:
2
,
deh_hops:
4
,
deh_len:
10
;
#endif
__u16
deh_sum
;
__u16
deh_dnet
;
...
...
@@ -92,30 +95,35 @@ struct ddpehdr
/* And netatalk apps expect to stick the type in themselves */
};
static
__inline__
struct
ddpehdr
*
ddp_hdr
(
struct
sk_buff
*
skb
)
{
return
(
struct
ddpehdr
*
)
skb
->
h
.
raw
;
}
/*
* Don't drop the struct into the struct above. You'll get some
* surprise padding.
*/
struct
ddpebits
{
struct
ddpebits
{
#ifdef __LITTLE_ENDIAN_BITFIELD
__u16
deh_len
:
10
,
deh_hops
:
4
,
deh_pad
:
2
;
__u16
deh_len
:
10
,
deh_hops:
4
,
deh_pad:
2
;
#else
__u16
deh_pad
:
2
,
deh_hops
:
4
,
deh_len
:
10
;
__u16
deh_pad
:
2
,
deh_hops:
4
,
deh_len:
10
;
#endif
};
/*
* Short form header
*/
struct
ddpshdr
{
/* Short form header */
struct
ddpshdr
{
#ifdef __LITTLE_ENDIAN_BITFIELD
__u16
dsh_len
:
10
,
dsh_pad
:
6
;
__u16
dsh_len
:
10
,
dsh_pad:
6
;
#else
__u16
dsh_pad
:
6
,
dsh_len
:
10
;
__u16
dsh_pad
:
6
,
dsh_len:
10
;
#endif
__u8
dsh_dport
;
__u8
dsh_sport
;
...
...
@@ -123,9 +131,7 @@ struct ddpshdr
};
/* AppleTalk AARP headers */
struct
elapaarp
{
struct
elapaarp
{
__u16
hw_type
;
#define AARP_HW_TYPE_ETHERNET 1
#define AARP_HW_TYPE_TOKENRING 2
...
...
@@ -147,30 +153,44 @@ struct elapaarp
__u8
pa_dst_node
__attribute__
((
packed
));
};
#define AARP_EXPIRY_TIME (5*60*HZ)
/* Not specified - how long till we drop a resolved entry */
#define AARP_HASH_SIZE 16
/* Size of hash table */
#define AARP_TICK_TIME (HZ/5)
/* Fast retransmission timer when resolving */
#define AARP_RETRANSMIT_LIMIT 10
/* Send 10 requests then give up (2 seconds) */
#define AARP_RESOLVE_TIME (10*HZ)
/* Some value bigger than total retransmit time + a bit for last reply to appear and to stop continual requests */
static
__inline__
struct
elapaarp
*
aarp_hdr
(
struct
sk_buff
*
skb
)
{
return
(
struct
elapaarp
*
)
skb
->
h
.
raw
;
}
/* Not specified - how long till we drop a resolved entry */
#define AARP_EXPIRY_TIME (5 * 60 * HZ)
/* Size of hash table */
#define AARP_HASH_SIZE 16
/* Fast retransmission timer when resolving */
#define AARP_TICK_TIME (HZ / 5)
/* Send 10 requests then give up (2 seconds) */
#define AARP_RETRANSMIT_LIMIT 10
/*
* Some value bigger than total retransmit time + a bit for last reply to
* appear and to stop continual requests
*/
#define AARP_RESOLVE_TIME (10 * HZ)
extern
struct
datalink_proto
*
ddp_dl
,
*
aarp_dl
;
extern
void
aarp_proto_init
(
void
);
/* Inter module exports */
/*
* Give a device find its atif control structure
*/
/* Inter module exports */
/* Give a device find its atif control structure */
static
inline
struct
atalk_iface
*
atalk_find_dev
(
struct
net_device
*
dev
)
{
return
dev
->
atalk_ptr
;
}
extern
struct
at_addr
*
atalk_find_dev_addr
(
struct
net_device
*
dev
);
extern
struct
net_device
*
atrtr_get_dev
(
struct
at_addr
*
sa
);
extern
int
aarp_send_ddp
(
struct
net_device
*
dev
,
struct
sk_buff
*
skb
,
struct
at_addr
*
sa
,
void
*
hwaddr
);
extern
void
aarp_send_probe
(
struct
net_device
*
dev
,
struct
at_addr
*
addr
);
extern
void
aarp_device_down
(
struct
net_device
*
dev
);
extern
struct
atalk_addr
*
atalk_find_dev_addr
(
struct
net_device
*
dev
);
extern
struct
net_device
*
atrtr_get_dev
(
struct
atalk_addr
*
sa
);
extern
int
aarp_send_ddp
(
struct
net_device
*
dev
,
struct
sk_buff
*
skb
,
struct
atalk_addr
*
sa
,
void
*
hwaddr
);
extern
void
aarp_send_probe
(
struct
net_device
*
dev
,
struct
atalk_addr
*
addr
);
extern
void
aarp_device_down
(
struct
net_device
*
dev
);
#ifdef MODULE
extern
void
aarp_cleanup_module
(
void
);
...
...
net/appletalk/aarp.c
View file @
be9ca388
...
...
@@ -30,7 +30,6 @@
*/
#include <linux/config.h>
#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/bitops.h>
...
...
@@ -84,7 +83,7 @@ struct aarp_entry {
struct
sk_buff_head
packet_queue
;
int
status
;
unsigned
long
expires_at
;
struct
at
_addr
target_addr
;
struct
at
alk_addr
target_addr
;
struct
net_device
*
dev
;
char
hwaddr
[
6
];
unsigned
short
xmit_count
;
...
...
@@ -122,14 +121,13 @@ static void __aarp_expire(struct aarp_entry *a)
static
void
__aarp_send_query
(
struct
aarp_entry
*
a
)
{
static
char
aarp_eth_multicast
[
ETH_ALEN
]
=
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
static
unsigned
char
aarp_eth_multicast
[
ETH_ALEN
]
=
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
struct
net_device
*
dev
=
a
->
dev
;
int
len
=
dev
->
hard_header_len
+
sizeof
(
struct
elapaarp
)
+
aarp_dl
->
header_length
;
struct
sk_buff
*
skb
=
alloc_skb
(
len
,
GFP_ATOMIC
);
struct
at_addr
*
sat
=
atalk_find_dev_addr
(
dev
);
struct
elapaarp
*
eah
;
int
len
=
dev
->
hard_header_len
+
sizeof
(
*
eah
)
+
aarp_dl
->
header_length
;
struct
sk_buff
*
skb
=
alloc_skb
(
len
,
GFP_ATOMIC
);
struct
atalk_addr
*
sat
=
atalk_find_dev_addr
(
dev
);
if
(
!
skb
)
return
;
...
...
@@ -141,30 +139,29 @@ static void __aarp_send_query(struct aarp_entry *a)
/* Set up the buffer */
skb_reserve
(
skb
,
dev
->
hard_header_len
+
aarp_dl
->
header_length
);
eah
=
(
struct
elapaarp
*
)
skb_put
(
skb
,
sizeof
(
struct
elapaarp
));
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
(
void
*
)
eah
;
skb
->
dev
=
dev
;
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
skb_put
(
skb
,
sizeof
(
*
eah
));
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
dev
=
dev
;
eah
=
aarp_hdr
(
skb
);
/* Set up the ARP */
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
eah
->
pa_type
=
htons
(
ETH_P_ATALK
);
eah
->
hw_len
=
ETH_ALEN
;
eah
->
pa_len
=
AARP_PA_ALEN
;
eah
->
function
=
htons
(
AARP_REQUEST
);
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
eah
->
pa_type
=
htons
(
ETH_P_ATALK
);
eah
->
hw_len
=
ETH_ALEN
;
eah
->
pa_len
=
AARP_PA_ALEN
;
eah
->
function
=
htons
(
AARP_REQUEST
);
memcpy
(
eah
->
hw_src
,
dev
->
dev_addr
,
ETH_ALEN
);
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_net
=
sat
->
s_net
;
eah
->
pa_src_node
=
sat
->
s_node
;
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_net
=
sat
->
s_net
;
eah
->
pa_src_node
=
sat
->
s_node
;
memset
(
eah
->
hw_dst
,
'\0'
,
ETH_ALEN
);
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_net
=
a
->
target_addr
.
s_net
;
eah
->
pa_dst_node
=
a
->
target_addr
.
s_node
;
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_net
=
a
->
target_addr
.
s_net
;
eah
->
pa_dst_node
=
a
->
target_addr
.
s_node
;
/* Add ELAP headers and set target to the AARP multicast */
aarp_dl
->
datalink_header
(
aarp_dl
,
skb
,
aarp_eth_multicast
);
...
...
@@ -177,46 +174,44 @@ static void __aarp_send_query(struct aarp_entry *a)
/* This runs under aarp_lock and in softint context, so only atomic memory
* allocations can be used. */
static
void
aarp_send_reply
(
struct
net_device
*
dev
,
struct
at_addr
*
us
,
struct
at_addr
*
them
,
unsigned
char
*
sha
)
static
void
aarp_send_reply
(
struct
net_device
*
dev
,
struct
at
alk
_addr
*
us
,
struct
at
alk
_addr
*
them
,
unsigned
char
*
sha
)
{
int
len
=
dev
->
hard_header_len
+
sizeof
(
struct
elapaarp
)
+
aarp_dl
->
header_length
;
struct
sk_buff
*
skb
=
alloc_skb
(
len
,
GFP_ATOMIC
);
struct
elapaarp
*
eah
;
int
len
=
dev
->
hard_header_len
+
sizeof
(
*
eah
)
+
aarp_dl
->
header_length
;
struct
sk_buff
*
skb
=
alloc_skb
(
len
,
GFP_ATOMIC
);
if
(
!
skb
)
return
;
/* Set up the buffer */
skb_reserve
(
skb
,
dev
->
hard_header_len
+
aarp_dl
->
header_length
);
eah
=
(
struct
elapaarp
*
)
skb_put
(
skb
,
sizeof
(
struct
elapaarp
));
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
(
void
*
)
eah
;
skb
->
dev
=
dev
;
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
skb_put
(
skb
,
sizeof
(
*
eah
));
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
dev
=
dev
;
eah
=
aarp_hdr
(
skb
);
/* Set up the ARP */
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
eah
->
pa_type
=
htons
(
ETH_P_ATALK
);
eah
->
hw_len
=
ETH_ALEN
;
eah
->
pa_len
=
AARP_PA_ALEN
;
eah
->
function
=
htons
(
AARP_REPLY
);
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
eah
->
pa_type
=
htons
(
ETH_P_ATALK
);
eah
->
hw_len
=
ETH_ALEN
;
eah
->
pa_len
=
AARP_PA_ALEN
;
eah
->
function
=
htons
(
AARP_REPLY
);
memcpy
(
eah
->
hw_src
,
dev
->
dev_addr
,
ETH_ALEN
);
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_net
=
us
->
s_net
;
eah
->
pa_src_node
=
us
->
s_node
;
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_net
=
us
->
s_net
;
eah
->
pa_src_node
=
us
->
s_node
;
if
(
!
sha
)
memset
(
eah
->
hw_dst
,
'\0'
,
ETH_ALEN
);
else
memcpy
(
eah
->
hw_dst
,
sha
,
ETH_ALEN
);
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_net
=
them
->
s_net
;
eah
->
pa_dst_node
=
them
->
s_node
;
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_net
=
them
->
s_net
;
eah
->
pa_dst_node
=
them
->
s_node
;
/* Add ELAP headers and set target to the AARP multicast */
aarp_dl
->
datalink_header
(
aarp_dl
,
skb
,
sha
);
...
...
@@ -229,44 +224,42 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
* aarp_proxy_probe_network.
*/
void
aarp_send_probe
(
struct
net_device
*
dev
,
struct
at_addr
*
us
)
void
aarp_send_probe
(
struct
net_device
*
dev
,
struct
at
alk
_addr
*
us
)
{
int
len
=
dev
->
hard_header_len
+
sizeof
(
struct
elapaarp
)
+
aarp_dl
->
header_length
;
struct
sk_buff
*
skb
=
alloc_skb
(
len
,
GFP_ATOMIC
);
static
char
aarp_eth_multicast
[
ETH_ALEN
]
=
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
struct
elapaarp
*
eah
;
int
len
=
dev
->
hard_header_len
+
sizeof
(
*
eah
)
+
aarp_dl
->
header_length
;
struct
sk_buff
*
skb
=
alloc_skb
(
len
,
GFP_ATOMIC
);
static
unsigned
char
aarp_eth_multicast
[
ETH_ALEN
]
=
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
if
(
!
skb
)
return
;
/* Set up the buffer */
skb_reserve
(
skb
,
dev
->
hard_header_len
+
aarp_dl
->
header_length
);
eah
=
(
struct
elapaarp
*
)
skb_put
(
skb
,
sizeof
(
struct
elapaarp
));
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
(
void
*
)
eah
;
skb
->
dev
=
dev
;
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
skb_put
(
skb
,
sizeof
(
*
eah
));
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
dev
=
dev
;
eah
=
aarp_hdr
(
skb
);
/* Set up the ARP */
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
eah
->
pa_type
=
htons
(
ETH_P_ATALK
);
eah
->
hw_len
=
ETH_ALEN
;
eah
->
pa_len
=
AARP_PA_ALEN
;
eah
->
function
=
htons
(
AARP_PROBE
);
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
eah
->
pa_type
=
htons
(
ETH_P_ATALK
);
eah
->
hw_len
=
ETH_ALEN
;
eah
->
pa_len
=
AARP_PA_ALEN
;
eah
->
function
=
htons
(
AARP_PROBE
);
memcpy
(
eah
->
hw_src
,
dev
->
dev_addr
,
ETH_ALEN
);
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_net
=
us
->
s_net
;
eah
->
pa_src_node
=
us
->
s_node
;
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_net
=
us
->
s_net
;
eah
->
pa_src_node
=
us
->
s_node
;
memset
(
eah
->
hw_dst
,
'\0'
,
ETH_ALEN
);
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_net
=
us
->
s_net
;
eah
->
pa_dst_node
=
us
->
s_node
;
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_net
=
us
->
s_net
;
eah
->
pa_dst_node
=
us
->
s_node
;
/* Add ELAP headers and set target to the AARP multicast */
aarp_dl
->
datalink_header
(
aarp_dl
,
skb
,
aarp_eth_multicast
);
...
...
@@ -398,7 +391,7 @@ static struct aarp_entry *aarp_alloc(void)
*/
static
struct
aarp_entry
*
__aarp_find_entry
(
struct
aarp_entry
*
list
,
struct
net_device
*
dev
,
struct
at_addr
*
sat
)
struct
at
alk
_addr
*
sat
)
{
while
(
list
)
{
if
(
list
->
target_addr
.
s_net
==
sat
->
s_net
&&
...
...
@@ -412,7 +405,7 @@ static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list,
}
/* Called from the DDP code, and thus must be exported. */
void
aarp_proxy_remove
(
struct
net_device
*
dev
,
struct
at_addr
*
sa
)
void
aarp_proxy_remove
(
struct
net_device
*
dev
,
struct
at
alk
_addr
*
sa
)
{
int
hash
=
sa
->
s_node
%
(
AARP_HASH_SIZE
-
1
);
struct
aarp_entry
*
a
;
...
...
@@ -427,8 +420,8 @@ void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa)
}
/* This must run under aarp_lock. */
static
struct
at_addr
*
__aarp_proxy_find
(
struct
net_device
*
dev
,
struct
at
_addr
*
sa
)
static
struct
at
alk
_addr
*
__aarp_proxy_find
(
struct
net_device
*
dev
,
struct
atalk
_addr
*
sa
)
{
int
hash
=
sa
->
s_node
%
(
AARP_HASH_SIZE
-
1
);
struct
aarp_entry
*
a
=
__aarp_find_entry
(
proxies
[
hash
],
dev
,
sa
);
...
...
@@ -482,7 +475,7 @@ void aarp_probe_network(struct atalk_iface *atif)
}
}
int
aarp_proxy_probe_network
(
struct
atalk_iface
*
atif
,
struct
at_addr
*
sa
)
int
aarp_proxy_probe_network
(
struct
atalk_iface
*
atif
,
struct
at
alk
_addr
*
sa
)
{
int
hash
,
retval
=
-
EPROTONOSUPPORT
;
struct
aarp_entry
*
entry
;
...
...
@@ -545,7 +538,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa)
/* Send a DDP frame */
int
aarp_send_ddp
(
struct
net_device
*
dev
,
struct
sk_buff
*
skb
,
struct
at
_addr
*
sa
,
void
*
hwaddr
)
struct
atalk
_addr
*
sa
,
void
*
hwaddr
)
{
static
char
ddp_eth_multicast
[
ETH_ALEN
]
=
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
...
...
@@ -556,15 +549,15 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
/* Check for LocalTalk first */
if
(
dev
->
type
==
ARPHRD_LOCALTLK
)
{
struct
at_addr
*
at
=
atalk_find_dev_addr
(
dev
);
struct
at
alk
_addr
*
at
=
atalk_find_dev_addr
(
dev
);
struct
ddpehdr
*
ddp
=
(
struct
ddpehdr
*
)
skb
->
data
;
int
ft
=
2
;
/*
*
Compressible ?
*
Compressible ?
*
*
IFF: src_net==dest_net==
device_net
*
(zero matches anything)
*
IFF: src_net == dest_net ==
device_net
*
(zero matches anything)
*/
if
((
!
ddp
->
deh_snet
||
at
->
s_net
==
ddp
->
deh_snet
)
&&
...
...
@@ -580,15 +573,15 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
ft
=
1
;
}
/*
*
Nice and easy. No AARP type protocols occur here
*
so we can
just shovel it out with a 3 byte LLAP header
*
Nice and easy. No AARP type protocols occur here so we can
* just shovel it out with a 3 byte LLAP header
*/
skb_push
(
skb
,
3
);
skb
->
data
[
0
]
=
sa
->
s_node
;
skb
->
data
[
1
]
=
at
->
s_node
;
skb
->
data
[
2
]
=
ft
;
skb
->
dev
=
dev
;
skb
->
dev
=
dev
;
goto
sendit
;
}
...
...
@@ -652,8 +645,8 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
__aarp_send_query
(
a
);
/*
*
Switch to fast timer if needed (That is if this is the
*
first
unresolved entry to get added)
*
Switch to fast timer if needed (That is if this is the first
* unresolved entry to get added)
*/
if
(
unresolved_count
==
1
)
...
...
@@ -713,11 +706,11 @@ static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a,
static
int
aarp_rcv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
)
{
struct
elapaarp
*
ea
=
(
struct
elapaarp
*
)
skb
->
h
.
raw
;
struct
elapaarp
*
ea
=
aarp_hdr
(
skb
)
;
int
hash
,
ret
=
0
;
__u16
function
;
struct
aarp_entry
*
a
;
struct
at_addr
sa
,
*
ma
,
da
;
struct
at
alk
_addr
sa
,
*
ma
,
da
;
struct
atalk_iface
*
ifa
;
/* We only do Ethernet SNAP AARP. */
...
...
@@ -791,20 +784,21 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
case
AARP_REQUEST
:
case
AARP_PROBE
:
/*
*
If it is my address set ma to my address and
*
reply. We can treat probe and request th
e
*
same. Probe simply means we shouldn't cache
*
the querying host, as in a probe they are
*
proposing an address not
using one.
*
If it is my address set ma to my address and reply.
*
We can treat probe and request the same. Prob
e
*
simply means we shouldn't cache the querying host,
*
as in a probe they are proposing an address not
* using one.
*
*
Support for proxy-AARP added. We check if the
*
address is one of our proxies before we toss
*
the
packet out.
*
Support for proxy-AARP added. We check if the
*
address is one of our proxies before we toss the
* packet out.
*/
sa
.
s_node
=
ea
->
pa_dst_node
;
sa
.
s_net
=
ea
->
pa_dst_net
;
sa
.
s_net
=
ea
->
pa_dst_net
;
/* See if we have a matching proxy. */
ma
=
__aarp_proxy_find
(
dev
,
&
sa
);
...
...
@@ -817,16 +811,22 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
}
if
(
function
==
AARP_PROBE
)
{
/* A probe implies someone trying to get an
/*
* A probe implies someone trying to get an
* address. So as a precaution flush any
* entries we have for this address. */
* entries we have for this address.
*/
struct
aarp_entry
*
a
=
__aarp_find_entry
(
resolved
[
sa
.
s_node
%
(
AARP_HASH_SIZE
-
1
)],
skb
->
dev
,
&
sa
);
/* Make it expire next tick - that avoids us
resolved
[
sa
.
s_node
%
(
AARP_HASH_SIZE
-
1
)],
skb
->
dev
,
&
sa
);
/*
* Make it expire next tick - that avoids us
* getting into a probe/flush/learn/probe/
* flush/learn cycle during probing of a slow
* to respond host addr. */
* to respond host addr.
*/
if
(
a
)
{
a
->
expires_at
=
jiffies
-
1
;
mod_timer
(
&
aarp_timer
,
jiffies
+
...
...
@@ -862,7 +862,7 @@ static struct notifier_block aarp_notifier = {
.
notifier_call
=
aarp_device_event
,
};
static
char
aarp_snap_id
[]
=
{
0x00
,
0x00
,
0x00
,
0x80
,
0xF3
};
static
unsigned
char
aarp_snap_id
[]
=
{
0x00
,
0x00
,
0x00
,
0x80
,
0xF3
};
void
__init
aarp_proto_init
(
void
)
{
...
...
@@ -1003,5 +1003,4 @@ void aarp_unregister_proc_fs(void)
proc_net_remove
(
"aarp"
);
}
#endif
#endif
/* CONFIG_ATALK || CONFIG_ATALK_MODULE */
MODULE_LICENSE
(
"GPL"
);
net/appletalk/ddp.c
View file @
be9ca388
...
...
@@ -49,7 +49,6 @@
*/
#include <linux/config.h>
#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/system.h>
...
...
@@ -96,8 +95,8 @@ extern void aarp_cleanup_module(void);
extern
void
aarp_probe_network
(
struct
atalk_iface
*
atif
);
extern
int
aarp_proxy_probe_network
(
struct
atalk_iface
*
atif
,
struct
at
_addr
*
sa
);
extern
void
aarp_proxy_remove
(
struct
net_device
*
dev
,
struct
at_addr
*
sa
);
struct
atalk
_addr
*
sa
);
extern
void
aarp_proxy_remove
(
struct
net_device
*
dev
,
struct
at
alk
_addr
*
sa
);
#ifdef CONFIG_SYSCTL
extern
inline
void
atalk_register_sysctl
(
void
);
...
...
@@ -332,7 +331,7 @@ static void atif_drop_device(struct net_device *dev)
}
static
struct
atalk_iface
*
atif_add_device
(
struct
net_device
*
dev
,
struct
at_addr
*
sa
)
struct
at
alk
_addr
*
sa
)
{
struct
atalk_iface
*
iface
;
...
...
@@ -407,7 +406,7 @@ static int atif_probe_device(struct atalk_iface *atif)
/* Perform AARP probing for a proxy address */
static
int
atif_proxy_probe_device
(
struct
atalk_iface
*
atif
,
struct
at_addr
*
proxy_addr
)
struct
at
alk
_addr
*
proxy_addr
)
{
int
netrange
=
ntohs
(
atif
->
nets
.
nr_lastnet
)
-
ntohs
(
atif
->
nets
.
nr_firstnet
)
+
1
;
...
...
@@ -451,16 +450,16 @@ static int atif_proxy_probe_device(struct atalk_iface *atif,
}
struct
at_addr
*
atalk_find_dev_addr
(
struct
net_device
*
dev
)
struct
at
alk
_addr
*
atalk_find_dev_addr
(
struct
net_device
*
dev
)
{
struct
atalk_iface
*
iface
=
dev
->
atalk_ptr
;
return
iface
?
&
iface
->
address
:
NULL
;
}
static
struct
at_addr
*
atalk_find_primary
(
void
)
static
struct
at
alk
_addr
*
atalk_find_primary
(
void
)
{
struct
atalk_iface
*
fiface
=
NULL
;
struct
at_addr
*
retval
;
struct
at
alk
_addr
*
retval
;
struct
atalk_iface
*
iface
;
/*
...
...
@@ -497,14 +496,17 @@ static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev)
struct
atalk_iface
*
iface
=
dev
->
atalk_ptr
;
if
(
!
iface
||
iface
->
status
&
ATIF_PROBE
)
return
NULL
;
goto
out_err
;
if
(
node
==
ATADDR_BCAST
||
iface
->
address
.
s_node
==
node
||
node
==
ATADDR_ANYNODE
)
return
iface
;
return
NULL
;
if
(
node
!=
ATADDR_BCAST
&&
iface
->
address
.
s_node
!=
node
&&
node
!=
ATADDR_ANYNODE
)
goto
out_err
;
out:
return
iface
;
out_err:
iface
=
NULL
;
goto
out
;
}
/* Find a match for a specific network:node pair */
...
...
@@ -537,7 +539,7 @@ static struct atalk_iface *atalk_find_interface(int net, int node)
* the socket (later on...). We know about host routes and the fact
* that a route must be direct to broadcast.
*/
static
struct
atalk_route
*
atrtr_find
(
struct
at_addr
*
target
)
static
struct
atalk_route
*
atrtr_find
(
struct
at
alk
_addr
*
target
)
{
/*
* we must search through all routes unless we find a
...
...
@@ -589,7 +591,7 @@ static struct atalk_route *atrtr_find(struct at_addr *target)
* Given an AppleTalk network, find the device to use. This can be
* a simple lookup.
*/
struct
net_device
*
atrtr_get_dev
(
struct
at_addr
*
sa
)
struct
net_device
*
atrtr_get_dev
(
struct
at
alk
_addr
*
sa
)
{
struct
atalk_route
*
atr
=
atrtr_find
(
sa
);
return
atr
?
atr
->
dev
:
NULL
;
...
...
@@ -598,9 +600,9 @@ struct net_device *atrtr_get_dev(struct at_addr *sa)
/* Set up a default router */
static
void
atrtr_set_default
(
struct
net_device
*
dev
)
{
atrtr_default
.
dev
=
dev
;
atrtr_default
.
flags
=
RTF_UP
;
atrtr_default
.
gateway
.
s_net
=
htons
(
0
);
atrtr_default
.
dev
=
dev
;
atrtr_default
.
flags
=
RTF_UP
;
atrtr_default
.
gateway
.
s_net
=
htons
(
0
);
atrtr_default
.
gateway
.
s_node
=
0
;
}
...
...
@@ -691,7 +693,7 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
}
/* Delete a route. Find it and discard it */
static
int
atrtr_delete
(
struct
at_addr
*
addr
)
static
int
atrtr_delete
(
struct
at
alk
_addr
*
addr
)
{
struct
atalk_route
**
r
=
&
atalk_router_list
;
int
retval
=
0
;
...
...
@@ -750,7 +752,7 @@ static inline void atalk_dev_down(struct net_device *dev)
* delete our use of them (iface and route).
*/
static
int
ddp_device_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
void
*
ptr
)
{
if
(
event
==
NETDEV_DOWN
)
/* Discard any use of this */
...
...
@@ -765,7 +767,7 @@ static int atif_ioctl(int cmd, void *arg)
{
static
char
aarp_mcast
[
6
]
=
{
0x09
,
0x00
,
0x00
,
0xFF
,
0xFF
,
0xFF
};
struct
ifreq
atreq
;
struct
netrange
*
nr
;
struct
atalk_
netrange
*
nr
;
struct
sockaddr_at
*
sa
;
struct
net_device
*
dev
;
struct
atalk_iface
*
atif
;
...
...
@@ -796,7 +798,7 @@ static int atif_ioctl(int cmd, void *arg)
dev
->
type
!=
ARPHRD_PPP
)
return
-
EPROTONOSUPPORT
;
nr
=
(
struct
netrange
*
)
&
sa
->
sat_zero
[
0
];
nr
=
(
struct
atalk_
netrange
*
)
&
sa
->
sat_zero
[
0
];
add_route
=
1
;
/*
...
...
@@ -936,7 +938,7 @@ static int atif_ioctl(int cmd, void *arg)
if
(
!
atif
)
return
-
EADDRNOTAVAIL
;
nr
=
(
struct
netrange
*
)
&
(
atif
->
nets
);
nr
=
(
struct
atalk_
netrange
*
)
&
(
atif
->
nets
);
/*
* Phase 1 is fine on Localtalk but we don't do
* Ethertalk phase 1. Anyone wanting to add it go ahead.
...
...
@@ -982,7 +984,6 @@ static int atif_ioctl(int cmd, void *arg)
/* Routing ioctl() calls */
static
int
atrtr_ioctl
(
unsigned
int
cmd
,
void
*
arg
)
{
struct
net_device
*
dev
=
NULL
;
struct
rtentry
rt
;
if
(
copy_from_user
(
&
rt
,
arg
,
sizeof
(
rt
)))
...
...
@@ -995,15 +996,19 @@ static int atrtr_ioctl(unsigned int cmd, void *arg)
return
atrtr_delete
(
&
((
struct
sockaddr_at
*
)
&
rt
.
rt_dst
)
->
sat_addr
);
case
SIOCADDRT
:
/* FIXME: the name of the device is still in user
* space, isn't it? */
case
SIOCADDRT
:
{
struct
net_device
*
dev
=
NULL
;
/*
* FIXME: the name of the device is still in user
* space, isn't it?
*/
if
(
rt
.
rt_dev
)
{
dev
=
__dev_get_by_name
(
rt
.
rt_dev
);
if
(
!
dev
)
return
-
ENODEV
;
}
return
atrtr_create
(
&
rt
,
dev
);
}
}
return
-
EINVAL
;
}
...
...
@@ -1159,14 +1164,13 @@ static int atalk_release(struct socket *sock)
{
struct
sock
*
sk
=
sock
->
sk
;
if
(
!
sk
)
goto
out
;
if
(
!
sk
->
dead
)
sk
->
state_change
(
sk
);
sk
->
dead
=
1
;
sock
->
sk
=
NULL
;
atalk_destroy_socket
(
sk
);
out:
if
(
sk
)
{
if
(
!
sk
->
dead
)
sk
->
state_change
(
sk
);
sk
->
dead
=
1
;
sock
->
sk
=
NULL
;
atalk_destroy_socket
(
sk
);
}
return
0
;
}
...
...
@@ -1222,7 +1226,7 @@ static int atalk_autobind(struct sock *sk)
{
struct
atalk_sock
*
at
=
at_sk
(
sk
);
struct
sockaddr_at
sat
;
struct
at_addr
*
ap
=
atalk_find_primary
();
struct
at
alk
_addr
*
ap
=
atalk_find_primary
();
int
n
=
-
EADDRNOTAVAIL
;
if
(
!
ap
||
ap
->
s_net
==
htons
(
ATADDR_ANYNET
))
...
...
@@ -1252,7 +1256,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return
-
EAFNOSUPPORT
;
if
(
addr
->
sat_addr
.
s_net
==
htons
(
ATADDR_ANYNET
))
{
struct
at_addr
*
ap
=
atalk_find_primary
();
struct
at
alk
_addr
*
ap
=
atalk_find_primary
();
if
(
!
ap
)
return
-
EADDRNOTAVAIL
;
...
...
@@ -1330,7 +1334,6 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
return
0
;
}
/*
* Find the name of an AppleTalk socket. Just copy the right
* fields into the sockaddr.
...
...
@@ -1366,22 +1369,140 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
return
0
;
}
#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE)
static
__inline__
int
is_ip_over_ddp
(
struct
sk_buff
*
skb
)
{
return
skb
->
data
[
12
]
==
22
;
}
static
int
handle_ip_over_ddp
(
struct
sk_buff
*
skb
)
{
struct
net_device
*
dev
=
__dev_get_by_name
(
"ipddp0"
);
struct
net_device_stats
*
stats
;
/* This needs to be able to handle ipddp"N" devices */
if
(
!
dev
)
return
-
ENODEV
;
skb
->
protocol
=
htons
(
ETH_P_IP
);
skb_pull
(
skb
,
13
);
skb
->
dev
=
dev
;
skb
->
h
.
raw
=
skb
->
data
;
stats
=
dev
->
priv
;
stats
->
rx_packets
++
;
stats
->
rx_bytes
+=
skb
->
len
+
13
;
netif_rx
(
skb
);
/* Send the SKB up to a higher place. */
return
0
;
}
#else
/* make it easy for gcc to optimize this test out, i.e. kill the code */
#define is_ip_over_ddp(skb) 0
#define handle_ip_over_ddp(skb) 0
#endif
static
void
atalk_route_packet
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
ddpehdr
*
ddp
,
struct
ddpebits
*
ddphv
,
int
origlen
)
{
struct
atalk_route
*
rt
;
struct
atalk_addr
ta
;
/*
* Don't route multicast, etc., packets, or packets sent to "this
* network"
*/
if
(
skb
->
pkt_type
!=
PACKET_HOST
||
!
ddp
->
deh_dnet
)
{
/*
* FIXME:
*
* Can it ever happen that a packet is from a PPP iface and
* needs to be broadcast onto the default network?
*/
if
(
dev
->
type
==
ARPHRD_PPP
)
printk
(
KERN_DEBUG
"AppleTalk: didn't forward broadcast "
"packet received from PPP iface
\n
"
);
goto
free_it
;
}
ta
.
s_net
=
ddp
->
deh_dnet
;
ta
.
s_node
=
ddp
->
deh_dnode
;
/* Route the packet */
rt
=
atrtr_find
(
&
ta
);
if
(
!
rt
||
ddphv
->
deh_hops
==
DDP_MAXHOPS
)
goto
free_it
;
/* FIXME: use skb->cb to be able to use shared skbs */
ddphv
->
deh_hops
++
;
/*
* Route goes through another gateway, so set the target to the
* gateway instead.
*/
if
(
rt
->
flags
&
RTF_GATEWAY
)
{
ta
.
s_net
=
rt
->
gateway
.
s_net
;
ta
.
s_node
=
rt
->
gateway
.
s_node
;
}
/* Fix up skb->len field */
skb_trim
(
skb
,
min_t
(
unsigned
int
,
origlen
,
(
rt
->
dev
->
hard_header_len
+
ddp_dl
->
header_length
+
ddphv
->
deh_len
)));
/* Mend the byte order */
/* FIXME: use skb->cb to be able to use shared skbs */
*
((
__u16
*
)
ddp
)
=
ntohs
(
*
((
__u16
*
)
ddphv
));
/*
* Send the buffer onwards
*
* Now we must always be careful. If it's come from LocalTalk to
* EtherTalk it might not fit
*
* Order matters here: If a packet has to be copied to make a new
* headroom (rare hopefully) then it won't need unsharing.
*
* Note. ddp-> becomes invalid at the realloc.
*/
if
(
skb_headroom
(
skb
)
<
22
)
{
/* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */
struct
sk_buff
*
nskb
=
skb_realloc_headroom
(
skb
,
32
);
kfree_skb
(
skb
);
if
(
!
nskb
)
goto
out
;
skb
=
nskb
;
}
else
skb
=
skb_unshare
(
skb
,
GFP_ATOMIC
);
/*
* If the buffer didn't vanish into the lack of space bitbucket we can
* send it.
*/
if
(
skb
&&
aarp_send_ddp
(
rt
->
dev
,
skb
,
&
ta
,
NULL
)
==
-
1
)
goto
free_it
;
out:
return
;
free_it:
kfree_skb
(
skb
);
}
/**
*
atalk_rcv - Receive a packet (in skb) from device dev
*
@skb - packet received
*
@dev - network device where the packet comes from
*
@pt - packet type
*
atalk_rcv - Receive a packet (in skb) from device dev
*
@skb - packet received
*
@dev - network device where the packet comes from
*
@pt - packet type
*
*
Receive a packet (in skb) from device dev. This has come from the SNAP
*
decoder, and on entry skb->h.raw is the DDP header, skb->len is the DDP
*
header, skb->len is the DDP length. The physical headers have been
*
extracted. PPP should probably pass frames marked as for this layer.
*
[ie ARPHRD_ETHERTALK]
*
Receive a packet (in skb) from device dev. This has come from the SNAP
*
decoder, and on entry skb->h.raw is the DDP header, skb->len is the DDP
*
header, skb->len is the DDP length. The physical headers have been
*
extracted. PPP should probably pass frames marked as for this layer.
*
[ie ARPHRD_ETHERTALK]
*/
static
int
atalk_rcv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
)
{
struct
ddpehdr
*
ddp
=
(
void
*
)
skb
->
h
.
raw
;
struct
ddpehdr
*
ddp
=
ddp_hdr
(
skb
)
;
struct
sock
*
sock
;
struct
atalk_iface
*
atif
;
struct
sockaddr_at
tosat
;
...
...
@@ -1432,106 +1553,13 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
/* Not ours, so we route the packet via the correct AppleTalk iface */
if
(
!
atif
)
{
struct
atalk_route
*
rt
;
struct
at_addr
ta
;
/*
* Don't route multicast, etc., packets, or packets
* sent to "this network"
*/
if
(
skb
->
pkt_type
!=
PACKET_HOST
||
!
ddp
->
deh_dnet
)
{
/* FIXME:
* Can it ever happen that a packet is from a PPP
* iface and needs to be broadcast onto the default
* network? */
if
(
dev
->
type
==
ARPHRD_PPP
)
printk
(
KERN_DEBUG
"AppleTalk: didn't forward "
"broadcast packet received "
"from PPP iface
\n
"
);
goto
freeit
;
}
ta
.
s_net
=
ddp
->
deh_dnet
;
ta
.
s_node
=
ddp
->
deh_dnode
;
/* Route the packet */
rt
=
atrtr_find
(
&
ta
);
if
(
!
rt
||
ddphv
.
deh_hops
==
DDP_MAXHOPS
)
goto
freeit
;
/* FIXME: use skb->cb to be able to use shared skbs */
ddphv
.
deh_hops
++
;
/*
* Route goes through another gateway, so
* set the target to the gateway instead.
*/
if
(
rt
->
flags
&
RTF_GATEWAY
)
{
ta
.
s_net
=
rt
->
gateway
.
s_net
;
ta
.
s_node
=
rt
->
gateway
.
s_node
;
}
/* Fix up skb->len field */
skb_trim
(
skb
,
min_t
(
unsigned
int
,
origlen
,
(
rt
->
dev
->
hard_header_len
+
ddp_dl
->
header_length
+
ddphv
.
deh_len
)));
/* Mend the byte order */
/* FIXME: use skb->cb to be able to use shared skbs */
*
((
__u16
*
)
ddp
)
=
ntohs
(
*
((
__u16
*
)
&
ddphv
));
/*
* Send the buffer onwards
*
* Now we must always be careful. If it's come from
* LocalTalk to EtherTalk it might not fit
*
* Order matters here: If a packet has to be copied
* to make a new headroom (rare hopefully) then it
* won't need unsharing.
*
* Note. ddp-> becomes invalid at the realloc.
*/
if
(
skb_headroom
(
skb
)
<
22
)
{
/* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */
struct
sk_buff
*
nskb
=
skb_realloc_headroom
(
skb
,
32
);
kfree_skb
(
skb
);
if
(
!
nskb
)
goto
out
;
skb
=
nskb
;
}
else
skb
=
skb_unshare
(
skb
,
GFP_ATOMIC
);
/*
* If the buffer didn't vanish into the lack of
* space bitbucket we can send it.
*/
if
(
skb
&&
aarp_send_ddp
(
rt
->
dev
,
skb
,
&
ta
,
NULL
)
==
-
1
)
goto
freeit
;
atalk_route_packet
(
skb
,
dev
,
ddp
,
&
ddphv
,
origlen
);
goto
out
;
}
#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE)
/* Check if IP-over-DDP */
if
(
skb
->
data
[
12
]
==
22
)
{
struct
net_device
*
dev
=
__dev_get_by_name
(
"ipddp0"
);
struct
net_device_stats
*
stats
;
/* This needs to be able to handle ipddp"N" devices */
if
(
!
dev
)
return
-
ENODEV
;
skb
->
protocol
=
htons
(
ETH_P_IP
);
skb_pull
(
skb
,
13
);
skb
->
dev
=
dev
;
skb
->
h
.
raw
=
skb
->
data
;
stats
=
dev
->
priv
;
stats
->
rx_packets
++
;
stats
->
rx_bytes
+=
skb
->
len
+
13
;
netif_rx
(
skb
);
/* Send the SKB up to a higher place. */
goto
out
;
}
#endif
/* if IP over DDP is not selected this code will be optimized out */
if
(
is_ip_over_ddp
(
skb
))
return
handle_ip_over_ddp
(
skb
);
/*
* Which socket - atalk_search_socket() looks for a *full match*
* of the <net, node, port> tuple.
...
...
@@ -1568,7 +1596,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
if
(
skb
->
mac
.
raw
[
2
]
==
1
)
{
struct
ddpehdr
*
ddp
;
/* Find our address */
struct
at_addr
*
ap
=
atalk_find_dev_addr
(
dev
);
struct
at
alk
_addr
*
ap
=
atalk_find_dev_addr
(
dev
);
if
(
!
ap
||
skb
->
len
<
sizeof
(
struct
ddpshdr
))
goto
freeit
;
...
...
@@ -1674,7 +1702,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len,
dev
=
rt
->
dev
;
}
else
{
struct
at_addr
at_hint
;
struct
at
alk
_addr
at_hint
;
at_hint
.
s_node
=
0
;
at_hint
.
s_net
=
at
->
src_net
;
...
...
@@ -1792,7 +1820,7 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size,
return
err
;
/* FIXME: use skb->cb to be able to use shared skbs */
ddp
=
(
struct
ddpehdr
*
)(
skb
->
h
.
raw
);
ddp
=
ddp_hdr
(
skb
);
*
((
__u16
*
)
&
ddphv
)
=
ntohs
(
*
((
__u16
*
)
ddp
));
if
(
sk
->
type
==
SOCK_RAW
)
{
...
...
@@ -1833,40 +1861,48 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size,
*/
static
int
atalk_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
long
amount
=
0
;
int
rc
=
-
EINVAL
;
struct
sock
*
sk
=
sock
->
sk
;
switch
(
cmd
)
{
/* Protocol layer */
case
TIOCOUTQ
:
amount
=
sk
->
sndbuf
-
atomic_read
(
&
sk
->
wmem_alloc
);
case
TIOCOUTQ
:
{
long
amount
=
sk
->
sndbuf
-
atomic_read
(
&
sk
->
wmem_alloc
);
if
(
amount
<
0
)
amount
=
0
;
rc
=
put_user
(
amount
,
(
int
*
)
arg
);
break
;
}
case
TIOCINQ
:
{
/*
* These two are safe on a single CPU system as only
* user tasks fiddle here
*/
struct
sk_buff
*
skb
=
skb_peek
(
&
sk
->
receive_queue
);
long
amount
=
0
;
if
(
skb
)
amount
=
skb
->
len
-
sizeof
(
struct
ddpehdr
);
rc
=
put_user
(
amount
,
(
int
*
)
arg
);
break
;
}
case
SIOCGSTAMP
:
if
(
!
sk
)
return
-
EINVAL
;
break
;
rc
=
-
ENOENT
;
if
(
!
sk
->
stamp
.
tv_sec
)
return
-
ENOENT
;
return
copy_to_user
((
void
*
)
arg
,
&
sk
->
stamp
,
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
break
;
rc
=
copy_to_user
((
void
*
)
arg
,
&
sk
->
stamp
,
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
break
;
/* Routing */
case
SIOCADDRT
:
case
SIOCDELRT
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
return
atrtr_ioctl
(
cmd
,
(
void
*
)
arg
);
rc
=
-
EPERM
;
if
(
capable
(
CAP_NET_ADMIN
))
rc
=
atrtr_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
/* Interface */
case
SIOCGIFADDR
:
case
SIOCSIFADDR
:
...
...
@@ -1874,15 +1910,11 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case
SIOCATALKDIFADDR
:
case
SIOCDIFADDR
:
case
SIOCSARP
:
/* proxy AARP */
case
SIOCDARP
:
{
/* proxy AARP */
int
ret
;
case
SIOCDARP
:
/* proxy AARP */
rtnl_lock
();
r
et
=
atif_ioctl
(
cmd
,
(
void
*
)
arg
);
r
c
=
atif_ioctl
(
cmd
,
(
void
*
)
arg
);
rtnl_unlock
();
return
ret
;
}
break
;
/* Physical layer ioctl calls */
case
SIOCSIFLINK
:
case
SIOCGIFHWADDR
:
...
...
@@ -1896,21 +1928,11 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case
SIOCGIFCOUNT
:
case
SIOCGIFINDEX
:
case
SIOCGIFNAME
:
return
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
case
SIOCSIFMETRIC
:
case
SIOCSIFBRDADDR
:
case
SIOCGIFNETMASK
:
case
SIOCSIFNETMASK
:
case
SIOCGIFMEM
:
case
SIOCSIFMEM
:
case
SIOCGIFDSTADDR
:
case
SIOCSIFDSTADDR
:
return
-
EINVAL
;
default:
return
-
EINVAL
;
rc
=
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
}
return
put_user
(
amount
,
(
int
*
)
arg
)
;
return
rc
;
}
static
struct
net_proto_family
atalk_family_ops
=
{
...
...
@@ -1955,7 +1977,7 @@ struct packet_type ppptalk_packet_type = {
.
func
=
atalk_rcv
,
};
static
char
ddp_snap_id
[]
=
{
0x08
,
0x00
,
0x07
,
0x80
,
0x9B
};
static
unsigned
char
ddp_snap_id
[]
=
{
0x08
,
0x00
,
0x07
,
0x80
,
0x9B
};
/* Export symbols for use by drivers when AppleTalk is a module */
EXPORT_SYMBOL
(
aarp_send_ddp
);
...
...
@@ -2023,4 +2045,3 @@ static void __exit atalk_exit(void)
}
module_exit
(
atalk_exit
);
#endif
/* MODULE */
#endif
/* CONFIG_ATALK || CONFIG_ATALK_MODULE */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment