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
Show 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
* The following are directly referenced from the University Of Michigan
* netatalk for compatibility reasons.
* netatalk for compatibility reasons.
*/
*/
#ifndef __LINUX_ATALK_H__
#define __LINUX_ATALK_H__
#define ATPORT_FIRST 1
#define ATPORT_FIRST 1
#define ATPORT_RESERVED 128
#define ATPORT_RESERVED 128
#define ATPORT_LAST 254
/* 254 is only legal on localtalk */
#define ATPORT_LAST 254
/* 254 is only legal on localtalk */
...
@@ -20,49 +18,51 @@
...
@@ -20,49 +18,51 @@
#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0)
#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0)
struct
at_addr
struct
atalk_addr
{
{
__u16
s_net
;
__u16
s_net
;
__u8
s_node
;
__u8
s_node
;
};
};
struct
sockaddr_at
struct
sockaddr_at
{
{
sa_family_t
sat_family
;
sa_family_t
sat_family
;
__u8
sat_port
;
__u8
sat_port
;
struct
at
_addr
sat_addr
;
struct
at
alk_addr
sat_addr
;
char
sat_zero
[
8
];
char
sat_zero
[
8
];
};
};
struct
netrange
struct
atalk_netrange
{
{
__u8
nr_phase
;
__u8
nr_phase
;
__u16
nr_firstnet
;
__u16
nr_firstnet
;
__u16
nr_lastnet
;
__u16
nr_lastnet
;
};
};
struct
atalk_route
struct
atalk_route
{
{
struct
net_device
*
dev
;
struct
net_device
*
dev
;
struct
at
_addr
target
;
struct
at
alk_addr
target
;
struct
at
_addr
gateway
;
struct
at
alk_addr
gateway
;
int
flags
;
int
flags
;
struct
atalk_route
*
next
;
struct
atalk_route
*
next
;
};
};
struct
atalk_iface
/**
{
* 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
net_device
*
dev
;
struct
at
_addr
address
;
/* Our address */
struct
at
alk_addr
address
;
int
status
;
/* What are we doing? */
int
status
;
#define ATIF_PROBE 1
/* Probing for an address */
#define ATIF_PROBE 1
/* Probing for an address */
#define ATIF_PROBE_FAIL 2
/* Probe collided */
#define ATIF_PROBE_FAIL 2
/* Probe collided */
struct
netrange
nets
;
/* Associated direct netrange */
struct
atalk_netrange
nets
;
struct
atalk_iface
*
next
;
struct
atalk_iface
*
next
;
};
};
struct
atalk_sock
struct
atalk_sock
{
{
unsigned
short
dest_net
;
unsigned
short
dest_net
;
unsigned
short
src_net
;
unsigned
short
src_net
;
unsigned
char
dest_node
;
unsigned
char
dest_node
;
...
@@ -75,12 +75,15 @@ struct atalk_sock
...
@@ -75,12 +75,15 @@ struct atalk_sock
#include <asm/byteorder.h>
#include <asm/byteorder.h>
struct
ddpehdr
struct
ddpehdr
{
{
#ifdef __LITTLE_ENDIAN_BITFIELD
#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
#else
__u16
deh_pad
:
2
,
deh_hops
:
4
,
deh_len
:
10
;
__u16
deh_pad
:
2
,
deh_hops:
4
,
deh_len:
10
;
#endif
#endif
__u16
deh_sum
;
__u16
deh_sum
;
__u16
deh_dnet
;
__u16
deh_dnet
;
...
@@ -92,30 +95,35 @@ struct ddpehdr
...
@@ -92,30 +95,35 @@ struct ddpehdr
/* And netatalk apps expect to stick the type in themselves */
/* 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
* Don't drop the struct into the struct above. You'll get some
* surprise padding.
* surprise padding.
*/
*/
struct
ddpebits
{
struct
ddpebits
{
#ifdef __LITTLE_ENDIAN_BITFIELD
#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
#else
__u16
deh_pad
:
2
,
deh_hops
:
4
,
deh_len
:
10
;
__u16
deh_pad
:
2
,
deh_hops:
4
,
deh_len:
10
;
#endif
#endif
};
};
/*
/* Short form header */
* Short form header
struct
ddpshdr
{
*/
struct
ddpshdr
{
#ifdef __LITTLE_ENDIAN_BITFIELD
#ifdef __LITTLE_ENDIAN_BITFIELD
__u16
dsh_len
:
10
,
dsh_pad
:
6
;
__u16
dsh_len
:
10
,
dsh_pad:
6
;
#else
#else
__u16
dsh_pad
:
6
,
dsh_len
:
10
;
__u16
dsh_pad
:
6
,
dsh_len:
10
;
#endif
#endif
__u8
dsh_dport
;
__u8
dsh_dport
;
__u8
dsh_sport
;
__u8
dsh_sport
;
...
@@ -123,9 +131,7 @@ struct ddpshdr
...
@@ -123,9 +131,7 @@ struct ddpshdr
};
};
/* AppleTalk AARP headers */
/* AppleTalk AARP headers */
struct
elapaarp
{
struct
elapaarp
{
__u16
hw_type
;
__u16
hw_type
;
#define AARP_HW_TYPE_ETHERNET 1
#define AARP_HW_TYPE_ETHERNET 1
#define AARP_HW_TYPE_TOKENRING 2
#define AARP_HW_TYPE_TOKENRING 2
...
@@ -147,29 +153,43 @@ struct elapaarp
...
@@ -147,29 +153,43 @@ struct elapaarp
__u8
pa_dst_node
__attribute__
((
packed
));
__u8
pa_dst_node
__attribute__
((
packed
));
};
};
#define AARP_EXPIRY_TIME (5*60*HZ)
/* Not specified - how long till we drop a resolved entry */
static
__inline__
struct
elapaarp
*
aarp_hdr
(
struct
sk_buff
*
skb
)
#define AARP_HASH_SIZE 16
/* Size of hash table */
{
#define AARP_TICK_TIME (HZ/5)
/* Fast retransmission timer when resolving */
return
(
struct
elapaarp
*
)
skb
->
h
.
raw
;
#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 */
/* 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
struct
datalink_proto
*
ddp_dl
,
*
aarp_dl
;
extern
void
aarp_proto_init
(
void
);
extern
void
aarp_proto_init
(
void
);
/* Inter module exports */
/*
/* Inter module exports */
* Give a device find its atif control structure
*/
/* Give a device find its atif control structure */
static
inline
struct
atalk_iface
*
atalk_find_dev
(
struct
net_device
*
dev
)
static
inline
struct
atalk_iface
*
atalk_find_dev
(
struct
net_device
*
dev
)
{
{
return
dev
->
atalk_ptr
;
return
dev
->
atalk_ptr
;
}
}
extern
struct
at_addr
*
atalk_find_dev_addr
(
struct
net_device
*
dev
);
extern
struct
atalk_addr
*
atalk_find_dev_addr
(
struct
net_device
*
dev
);
extern
struct
net_device
*
atrtr_get_dev
(
struct
at_addr
*
sa
);
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
at_addr
*
sa
,
void
*
hwaddr
);
extern
int
aarp_send_ddp
(
struct
net_device
*
dev
,
extern
void
aarp_send_probe
(
struct
net_device
*
dev
,
struct
at_addr
*
addr
);
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
);
extern
void
aarp_device_down
(
struct
net_device
*
dev
);
#ifdef MODULE
#ifdef MODULE
...
...
net/appletalk/aarp.c
View file @
be9ca388
...
@@ -30,7 +30,6 @@
...
@@ -30,7 +30,6 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/bitops.h>
...
@@ -84,7 +83,7 @@ struct aarp_entry {
...
@@ -84,7 +83,7 @@ struct aarp_entry {
struct
sk_buff_head
packet_queue
;
struct
sk_buff_head
packet_queue
;
int
status
;
int
status
;
unsigned
long
expires_at
;
unsigned
long
expires_at
;
struct
at
_addr
target_addr
;
struct
at
alk_addr
target_addr
;
struct
net_device
*
dev
;
struct
net_device
*
dev
;
char
hwaddr
[
6
];
char
hwaddr
[
6
];
unsigned
short
xmit_count
;
unsigned
short
xmit_count
;
...
@@ -122,14 +121,13 @@ static void __aarp_expire(struct aarp_entry *a)
...
@@ -122,14 +121,13 @@ static void __aarp_expire(struct aarp_entry *a)
static
void
__aarp_send_query
(
struct
aarp_entry
*
a
)
static
void
__aarp_send_query
(
struct
aarp_entry
*
a
)
{
{
static
char
aarp_eth_multicast
[
ETH_ALEN
]
=
static
unsigned
char
aarp_eth_multicast
[
ETH_ALEN
]
=
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
struct
net_device
*
dev
=
a
->
dev
;
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
;
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
)
if
(
!
skb
)
return
;
return
;
...
@@ -141,11 +139,10 @@ static void __aarp_send_query(struct aarp_entry *a)
...
@@ -141,11 +139,10 @@ static void __aarp_send_query(struct aarp_entry *a)
/* Set up the buffer */
/* Set up the buffer */
skb_reserve
(
skb
,
dev
->
hard_header_len
+
aarp_dl
->
header_length
);
skb_reserve
(
skb
,
dev
->
hard_header_len
+
aarp_dl
->
header_length
);
eah
=
(
struct
elapaarp
*
)
skb_put
(
skb
,
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
skb_put
(
skb
,
sizeof
(
*
eah
));
sizeof
(
struct
elapaarp
));
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
(
void
*
)
eah
;
skb
->
dev
=
dev
;
skb
->
dev
=
dev
;
eah
=
aarp_hdr
(
skb
);
/* Set up the ARP */
/* Set up the ARP */
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
...
@@ -156,15 +153,15 @@ static void __aarp_send_query(struct aarp_entry *a)
...
@@ -156,15 +153,15 @@ static void __aarp_send_query(struct aarp_entry *a)
memcpy
(
eah
->
hw_src
,
dev
->
dev_addr
,
ETH_ALEN
);
memcpy
(
eah
->
hw_src
,
dev
->
dev_addr
,
ETH_ALEN
);
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_net
=
sat
->
s_net
;
eah
->
pa_src_net
=
sat
->
s_net
;
eah
->
pa_src_node
=
sat
->
s_node
;
eah
->
pa_src_node
=
sat
->
s_node
;
memset
(
eah
->
hw_dst
,
'\0'
,
ETH_ALEN
);
memset
(
eah
->
hw_dst
,
'\0'
,
ETH_ALEN
);
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_net
=
a
->
target_addr
.
s_net
;
eah
->
pa_dst_net
=
a
->
target_addr
.
s_net
;
eah
->
pa_dst_node
=
a
->
target_addr
.
s_node
;
eah
->
pa_dst_node
=
a
->
target_addr
.
s_node
;
/* Add ELAP headers and set target to the AARP multicast */
/* Add ELAP headers and set target to the AARP multicast */
aarp_dl
->
datalink_header
(
aarp_dl
,
skb
,
aarp_eth_multicast
);
aarp_dl
->
datalink_header
(
aarp_dl
,
skb
,
aarp_eth_multicast
);
...
@@ -177,24 +174,22 @@ static void __aarp_send_query(struct aarp_entry *a)
...
@@ -177,24 +174,22 @@ static void __aarp_send_query(struct aarp_entry *a)
/* This runs under aarp_lock and in softint context, so only atomic memory
/* This runs under aarp_lock and in softint context, so only atomic memory
* allocations can be used. */
* allocations can be used. */
static
void
aarp_send_reply
(
struct
net_device
*
dev
,
struct
at_addr
*
us
,
static
void
aarp_send_reply
(
struct
net_device
*
dev
,
struct
at
alk
_addr
*
us
,
struct
at_addr
*
them
,
unsigned
char
*
sha
)
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
;
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
)
if
(
!
skb
)
return
;
return
;
/* Set up the buffer */
/* Set up the buffer */
skb_reserve
(
skb
,
dev
->
hard_header_len
+
aarp_dl
->
header_length
);
skb_reserve
(
skb
,
dev
->
hard_header_len
+
aarp_dl
->
header_length
);
eah
=
(
struct
elapaarp
*
)
skb_put
(
skb
,
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
skb_put
(
skb
,
sizeof
(
*
eah
));
sizeof
(
struct
elapaarp
));
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
(
void
*
)
eah
;
skb
->
dev
=
dev
;
skb
->
dev
=
dev
;
eah
=
aarp_hdr
(
skb
);
/* Set up the ARP */
/* Set up the ARP */
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
...
@@ -205,18 +200,18 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
...
@@ -205,18 +200,18 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
memcpy
(
eah
->
hw_src
,
dev
->
dev_addr
,
ETH_ALEN
);
memcpy
(
eah
->
hw_src
,
dev
->
dev_addr
,
ETH_ALEN
);
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_net
=
us
->
s_net
;
eah
->
pa_src_net
=
us
->
s_net
;
eah
->
pa_src_node
=
us
->
s_node
;
eah
->
pa_src_node
=
us
->
s_node
;
if
(
!
sha
)
if
(
!
sha
)
memset
(
eah
->
hw_dst
,
'\0'
,
ETH_ALEN
);
memset
(
eah
->
hw_dst
,
'\0'
,
ETH_ALEN
);
else
else
memcpy
(
eah
->
hw_dst
,
sha
,
ETH_ALEN
);
memcpy
(
eah
->
hw_dst
,
sha
,
ETH_ALEN
);
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_net
=
them
->
s_net
;
eah
->
pa_dst_net
=
them
->
s_net
;
eah
->
pa_dst_node
=
them
->
s_node
;
eah
->
pa_dst_node
=
them
->
s_node
;
/* Add ELAP headers and set target to the AARP multicast */
/* Add ELAP headers and set target to the AARP multicast */
aarp_dl
->
datalink_header
(
aarp_dl
,
skb
,
sha
);
aarp_dl
->
datalink_header
(
aarp_dl
,
skb
,
sha
);
...
@@ -229,25 +224,23 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
...
@@ -229,25 +224,23 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
* aarp_proxy_probe_network.
* 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
)
+
struct
elapaarp
*
eah
;
aarp_dl
->
header_length
;
int
len
=
dev
->
hard_header_len
+
sizeof
(
*
eah
)
+
aarp_dl
->
header_length
;
struct
sk_buff
*
skb
=
alloc_skb
(
len
,
GFP_ATOMIC
);
struct
sk_buff
*
skb
=
alloc_skb
(
len
,
GFP_ATOMIC
);
static
char
aarp_eth_multicast
[
ETH_ALEN
]
=
static
unsigned
char
aarp_eth_multicast
[
ETH_ALEN
]
=
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
struct
elapaarp
*
eah
;
if
(
!
skb
)
if
(
!
skb
)
return
;
return
;
/* Set up the buffer */
/* Set up the buffer */
skb_reserve
(
skb
,
dev
->
hard_header_len
+
aarp_dl
->
header_length
);
skb_reserve
(
skb
,
dev
->
hard_header_len
+
aarp_dl
->
header_length
);
eah
=
(
struct
elapaarp
*
)
skb_put
(
skb
,
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
skb_put
(
skb
,
sizeof
(
*
eah
));
sizeof
(
struct
elapaarp
));
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
protocol
=
htons
(
ETH_P_ATALK
);
skb
->
nh
.
raw
=
skb
->
h
.
raw
=
(
void
*
)
eah
;
skb
->
dev
=
dev
;
skb
->
dev
=
dev
;
eah
=
aarp_hdr
(
skb
);
/* Set up the ARP */
/* Set up the ARP */
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
eah
->
hw_type
=
htons
(
AARP_HW_TYPE_ETHERNET
);
...
@@ -258,15 +251,15 @@ void aarp_send_probe(struct net_device *dev, struct at_addr *us)
...
@@ -258,15 +251,15 @@ void aarp_send_probe(struct net_device *dev, struct at_addr *us)
memcpy
(
eah
->
hw_src
,
dev
->
dev_addr
,
ETH_ALEN
);
memcpy
(
eah
->
hw_src
,
dev
->
dev_addr
,
ETH_ALEN
);
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_zero
=
0
;
eah
->
pa_src_net
=
us
->
s_net
;
eah
->
pa_src_net
=
us
->
s_net
;
eah
->
pa_src_node
=
us
->
s_node
;
eah
->
pa_src_node
=
us
->
s_node
;
memset
(
eah
->
hw_dst
,
'\0'
,
ETH_ALEN
);
memset
(
eah
->
hw_dst
,
'\0'
,
ETH_ALEN
);
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_zero
=
0
;
eah
->
pa_dst_net
=
us
->
s_net
;
eah
->
pa_dst_net
=
us
->
s_net
;
eah
->
pa_dst_node
=
us
->
s_node
;
eah
->
pa_dst_node
=
us
->
s_node
;
/* Add ELAP headers and set target to the AARP multicast */
/* Add ELAP headers and set target to the AARP multicast */
aarp_dl
->
datalink_header
(
aarp_dl
,
skb
,
aarp_eth_multicast
);
aarp_dl
->
datalink_header
(
aarp_dl
,
skb
,
aarp_eth_multicast
);
...
@@ -398,7 +391,7 @@ static struct aarp_entry *aarp_alloc(void)
...
@@ -398,7 +391,7 @@ static struct aarp_entry *aarp_alloc(void)
*/
*/
static
struct
aarp_entry
*
__aarp_find_entry
(
struct
aarp_entry
*
list
,
static
struct
aarp_entry
*
__aarp_find_entry
(
struct
aarp_entry
*
list
,
struct
net_device
*
dev
,
struct
net_device
*
dev
,
struct
at_addr
*
sat
)
struct
at
alk
_addr
*
sat
)
{
{
while
(
list
)
{
while
(
list
)
{
if
(
list
->
target_addr
.
s_net
==
sat
->
s_net
&&
if
(
list
->
target_addr
.
s_net
==
sat
->
s_net
&&
...
@@ -412,7 +405,7 @@ static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list,
...
@@ -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. */
/* 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
);
int
hash
=
sa
->
s_node
%
(
AARP_HASH_SIZE
-
1
);
struct
aarp_entry
*
a
;
struct
aarp_entry
*
a
;
...
@@ -427,8 +420,8 @@ void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa)
...
@@ -427,8 +420,8 @@ void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa)
}
}
/* This must run under aarp_lock. */
/* This must run under aarp_lock. */
static
struct
at_addr
*
__aarp_proxy_find
(
struct
net_device
*
dev
,
static
struct
at
alk
_addr
*
__aarp_proxy_find
(
struct
net_device
*
dev
,
struct
at
_addr
*
sa
)
struct
atalk
_addr
*
sa
)
{
{
int
hash
=
sa
->
s_node
%
(
AARP_HASH_SIZE
-
1
);
int
hash
=
sa
->
s_node
%
(
AARP_HASH_SIZE
-
1
);
struct
aarp_entry
*
a
=
__aarp_find_entry
(
proxies
[
hash
],
dev
,
sa
);
struct
aarp_entry
*
a
=
__aarp_find_entry
(
proxies
[
hash
],
dev
,
sa
);
...
@@ -482,7 +475,7 @@ void aarp_probe_network(struct atalk_iface *atif)
...
@@ -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
;
int
hash
,
retval
=
-
EPROTONOSUPPORT
;
struct
aarp_entry
*
entry
;
struct
aarp_entry
*
entry
;
...
@@ -545,7 +538,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa)
...
@@ -545,7 +538,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa)
/* Send a DDP frame */
/* Send a DDP frame */
int
aarp_send_ddp
(
struct
net_device
*
dev
,
struct
sk_buff
*
skb
,
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
]
=
static
char
ddp_eth_multicast
[
ETH_ALEN
]
=
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
{
0x09
,
0x00
,
0x07
,
0xFF
,
0xFF
,
0xFF
};
...
@@ -556,14 +549,14 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
...
@@ -556,14 +549,14 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
/* Check for LocalTalk first */
/* Check for LocalTalk first */
if
(
dev
->
type
==
ARPHRD_LOCALTLK
)
{
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
;
struct
ddpehdr
*
ddp
=
(
struct
ddpehdr
*
)
skb
->
data
;
int
ft
=
2
;
int
ft
=
2
;
/*
/*
* Compressible ?
* Compressible ?
*
*
*
IFF: src_net==dest_net==
device_net
*
IFF: src_net == dest_net ==
device_net
* (zero matches anything)
* (zero matches anything)
*/
*/
...
@@ -580,8 +573,8 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
...
@@ -580,8 +573,8 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
ft
=
1
;
ft
=
1
;
}
}
/*
/*
*
Nice and easy. No AARP type protocols occur here
*
Nice and easy. No AARP type protocols occur here so we can
*
so we can
just shovel it out with a 3 byte LLAP header
* just shovel it out with a 3 byte LLAP header
*/
*/
skb_push
(
skb
,
3
);
skb_push
(
skb
,
3
);
...
@@ -652,8 +645,8 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
...
@@ -652,8 +645,8 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
__aarp_send_query
(
a
);
__aarp_send_query
(
a
);
/*
/*
*
Switch to fast timer if needed (That is if this is the
*
Switch to fast timer if needed (That is if this is the first
*
first
unresolved entry to get added)
* unresolved entry to get added)
*/
*/
if
(
unresolved_count
==
1
)
if
(
unresolved_count
==
1
)
...
@@ -713,11 +706,11 @@ static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a,
...
@@ -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
,
static
int
aarp_rcv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
)
struct
packet_type
*
pt
)
{
{
struct
elapaarp
*
ea
=
(
struct
elapaarp
*
)
skb
->
h
.
raw
;
struct
elapaarp
*
ea
=
aarp_hdr
(
skb
)
;
int
hash
,
ret
=
0
;
int
hash
,
ret
=
0
;
__u16
function
;
__u16
function
;
struct
aarp_entry
*
a
;
struct
aarp_entry
*
a
;
struct
at_addr
sa
,
*
ma
,
da
;
struct
at
alk
_addr
sa
,
*
ma
,
da
;
struct
atalk_iface
*
ifa
;
struct
atalk_iface
*
ifa
;
/* We only do Ethernet SNAP AARP. */
/* We only do Ethernet SNAP AARP. */
...
@@ -791,16 +784,17 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
...
@@ -791,16 +784,17 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
case
AARP_REQUEST
:
case
AARP_REQUEST
:
case
AARP_PROBE
:
case
AARP_PROBE
:
/*
/*
*
If it is my address set ma to my address and
*
If it is my address set ma to my address and reply.
*
reply. We can treat probe and request th
e
*
We can treat probe and request the same. Prob
e
*
same. Probe simply means we shouldn't cache
*
simply means we shouldn't cache the querying host,
*
the querying host, as in a probe they are
*
as in a probe they are proposing an address not
*
proposing an address not
using one.
* using one.
*
*
* Support for proxy-AARP added. We check if the
* Support for proxy-AARP added. We check if the
*
address is one of our proxies before we toss
*
address is one of our proxies before we toss the
*
the
packet out.
* packet out.
*/
*/
sa
.
s_node
=
ea
->
pa_dst_node
;
sa
.
s_node
=
ea
->
pa_dst_node
;
...
@@ -817,16 +811,22 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
...
@@ -817,16 +811,22 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
}
}
if
(
function
==
AARP_PROBE
)
{
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
* 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
(
struct
aarp_entry
*
a
=
__aarp_find_entry
(
resolved
[
sa
.
s_node
%
(
AARP_HASH_SIZE
-
1
)],
resolved
[
sa
.
s_node
%
(
AARP_HASH_SIZE
-
1
)],
skb
->
dev
,
&
sa
);
skb
->
dev
,
&
sa
);
/* Make it expire next tick - that avoids us
/*
* Make it expire next tick - that avoids us
* getting into a probe/flush/learn/probe/
* getting into a probe/flush/learn/probe/
* flush/learn cycle during probing of a slow
* flush/learn cycle during probing of a slow
* to respond host addr. */
* to respond host addr.
*/
if
(
a
)
{
if
(
a
)
{
a
->
expires_at
=
jiffies
-
1
;
a
->
expires_at
=
jiffies
-
1
;
mod_timer
(
&
aarp_timer
,
jiffies
+
mod_timer
(
&
aarp_timer
,
jiffies
+
...
@@ -862,7 +862,7 @@ static struct notifier_block aarp_notifier = {
...
@@ -862,7 +862,7 @@ static struct notifier_block aarp_notifier = {
.
notifier_call
=
aarp_device_event
,
.
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
)
void
__init
aarp_proto_init
(
void
)
{
{
...
@@ -1003,5 +1003,4 @@ void aarp_unregister_proc_fs(void)
...
@@ -1003,5 +1003,4 @@ void aarp_unregister_proc_fs(void)
proc_net_remove
(
"aarp"
);
proc_net_remove
(
"aarp"
);
}
}
#endif
#endif
#endif
/* CONFIG_ATALK || CONFIG_ATALK_MODULE */
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
net/appletalk/ddp.c
View file @
be9ca388
...
@@ -49,7 +49,6 @@
...
@@ -49,7 +49,6 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
#include <linux/module.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/system.h>
...
@@ -96,8 +95,8 @@ extern void aarp_cleanup_module(void);
...
@@ -96,8 +95,8 @@ extern void aarp_cleanup_module(void);
extern
void
aarp_probe_network
(
struct
atalk_iface
*
atif
);
extern
void
aarp_probe_network
(
struct
atalk_iface
*
atif
);
extern
int
aarp_proxy_probe_network
(
struct
atalk_iface
*
atif
,
extern
int
aarp_proxy_probe_network
(
struct
atalk_iface
*
atif
,
struct
at
_addr
*
sa
);
struct
atalk
_addr
*
sa
);
extern
void
aarp_proxy_remove
(
struct
net_device
*
dev
,
struct
at_addr
*
sa
);
extern
void
aarp_proxy_remove
(
struct
net_device
*
dev
,
struct
at
alk
_addr
*
sa
);
#ifdef CONFIG_SYSCTL
#ifdef CONFIG_SYSCTL
extern
inline
void
atalk_register_sysctl
(
void
);
extern
inline
void
atalk_register_sysctl
(
void
);
...
@@ -332,7 +331,7 @@ static void atif_drop_device(struct net_device *dev)
...
@@ -332,7 +331,7 @@ static void atif_drop_device(struct net_device *dev)
}
}
static
struct
atalk_iface
*
atif_add_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
;
struct
atalk_iface
*
iface
;
...
@@ -407,7 +406,7 @@ static int atif_probe_device(struct atalk_iface *atif)
...
@@ -407,7 +406,7 @@ static int atif_probe_device(struct atalk_iface *atif)
/* Perform AARP probing for a proxy address */
/* Perform AARP probing for a proxy address */
static
int
atif_proxy_probe_device
(
struct
atalk_iface
*
atif
,
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
)
-
int
netrange
=
ntohs
(
atif
->
nets
.
nr_lastnet
)
-
ntohs
(
atif
->
nets
.
nr_firstnet
)
+
1
;
ntohs
(
atif
->
nets
.
nr_firstnet
)
+
1
;
...
@@ -451,16 +450,16 @@ static int atif_proxy_probe_device(struct atalk_iface *atif,
...
@@ -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
;
struct
atalk_iface
*
iface
=
dev
->
atalk_ptr
;
return
iface
?
&
iface
->
address
:
NULL
;
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
atalk_iface
*
fiface
=
NULL
;
struct
at_addr
*
retval
;
struct
at
alk
_addr
*
retval
;
struct
atalk_iface
*
iface
;
struct
atalk_iface
*
iface
;
/*
/*
...
@@ -497,14 +496,17 @@ static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev)
...
@@ -497,14 +496,17 @@ static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev)
struct
atalk_iface
*
iface
=
dev
->
atalk_ptr
;
struct
atalk_iface
*
iface
=
dev
->
atalk_ptr
;
if
(
!
iface
||
iface
->
status
&
ATIF_PROBE
)
if
(
!
iface
||
iface
->
status
&
ATIF_PROBE
)
return
NULL
;
goto
out_err
;
if
(
node
==
ATADDR_BCAST
||
if
(
node
!=
ATADDR_BCAST
&&
iface
->
address
.
s_node
==
node
||
iface
->
address
.
s_node
!=
node
&&
node
==
ATADDR_ANYNODE
)
node
!=
ATADDR_ANYNODE
)
goto
out_err
;
out:
return
iface
;
return
iface
;
out_err:
return
NULL
;
iface
=
NULL
;
goto
out
;
}
}
/* Find a match for a specific network:node pair */
/* Find a match for a specific network:node pair */
...
@@ -537,7 +539,7 @@ static struct atalk_iface *atalk_find_interface(int net, int node)
...
@@ -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
* the socket (later on...). We know about host routes and the fact
* that a route must be direct to broadcast.
* 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
* we must search through all routes unless we find a
...
@@ -589,7 +591,7 @@ static struct atalk_route *atrtr_find(struct at_addr *target)
...
@@ -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
* Given an AppleTalk network, find the device to use. This can be
* a simple lookup.
* 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
);
struct
atalk_route
*
atr
=
atrtr_find
(
sa
);
return
atr
?
atr
->
dev
:
NULL
;
return
atr
?
atr
->
dev
:
NULL
;
...
@@ -691,7 +693,7 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
...
@@ -691,7 +693,7 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
}
}
/* Delete a route. Find it and discard it */
/* 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
;
struct
atalk_route
**
r
=
&
atalk_router_list
;
int
retval
=
0
;
int
retval
=
0
;
...
@@ -765,7 +767,7 @@ static int atif_ioctl(int cmd, void *arg)
...
@@ -765,7 +767,7 @@ static int atif_ioctl(int cmd, void *arg)
{
{
static
char
aarp_mcast
[
6
]
=
{
0x09
,
0x00
,
0x00
,
0xFF
,
0xFF
,
0xFF
};
static
char
aarp_mcast
[
6
]
=
{
0x09
,
0x00
,
0x00
,
0xFF
,
0xFF
,
0xFF
};
struct
ifreq
atreq
;
struct
ifreq
atreq
;
struct
netrange
*
nr
;
struct
atalk_
netrange
*
nr
;
struct
sockaddr_at
*
sa
;
struct
sockaddr_at
*
sa
;
struct
net_device
*
dev
;
struct
net_device
*
dev
;
struct
atalk_iface
*
atif
;
struct
atalk_iface
*
atif
;
...
@@ -796,7 +798,7 @@ static int atif_ioctl(int cmd, void *arg)
...
@@ -796,7 +798,7 @@ static int atif_ioctl(int cmd, void *arg)
dev
->
type
!=
ARPHRD_PPP
)
dev
->
type
!=
ARPHRD_PPP
)
return
-
EPROTONOSUPPORT
;
return
-
EPROTONOSUPPORT
;
nr
=
(
struct
netrange
*
)
&
sa
->
sat_zero
[
0
];
nr
=
(
struct
atalk_
netrange
*
)
&
sa
->
sat_zero
[
0
];
add_route
=
1
;
add_route
=
1
;
/*
/*
...
@@ -936,7 +938,7 @@ static int atif_ioctl(int cmd, void *arg)
...
@@ -936,7 +938,7 @@ static int atif_ioctl(int cmd, void *arg)
if
(
!
atif
)
if
(
!
atif
)
return
-
EADDRNOTAVAIL
;
return
-
EADDRNOTAVAIL
;
nr
=
(
struct
netrange
*
)
&
(
atif
->
nets
);
nr
=
(
struct
atalk_
netrange
*
)
&
(
atif
->
nets
);
/*
/*
* Phase 1 is fine on Localtalk but we don't do
* Phase 1 is fine on Localtalk but we don't do
* Ethertalk phase 1. Anyone wanting to add it go ahead.
* Ethertalk phase 1. Anyone wanting to add it go ahead.
...
@@ -982,7 +984,6 @@ static int atif_ioctl(int cmd, void *arg)
...
@@ -982,7 +984,6 @@ static int atif_ioctl(int cmd, void *arg)
/* Routing ioctl() calls */
/* Routing ioctl() calls */
static
int
atrtr_ioctl
(
unsigned
int
cmd
,
void
*
arg
)
static
int
atrtr_ioctl
(
unsigned
int
cmd
,
void
*
arg
)
{
{
struct
net_device
*
dev
=
NULL
;
struct
rtentry
rt
;
struct
rtentry
rt
;
if
(
copy_from_user
(
&
rt
,
arg
,
sizeof
(
rt
)))
if
(
copy_from_user
(
&
rt
,
arg
,
sizeof
(
rt
)))
...
@@ -995,9 +996,12 @@ static int atrtr_ioctl(unsigned int cmd, void *arg)
...
@@ -995,9 +996,12 @@ static int atrtr_ioctl(unsigned int cmd, void *arg)
return
atrtr_delete
(
&
((
struct
sockaddr_at
*
)
return
atrtr_delete
(
&
((
struct
sockaddr_at
*
)
&
rt
.
rt_dst
)
->
sat_addr
);
&
rt
.
rt_dst
)
->
sat_addr
);
case
SIOCADDRT
:
case
SIOCADDRT
:
{
/* FIXME: the name of the device is still in user
struct
net_device
*
dev
=
NULL
;
* space, isn't it? */
/*
* FIXME: the name of the device is still in user
* space, isn't it?
*/
if
(
rt
.
rt_dev
)
{
if
(
rt
.
rt_dev
)
{
dev
=
__dev_get_by_name
(
rt
.
rt_dev
);
dev
=
__dev_get_by_name
(
rt
.
rt_dev
);
if
(
!
dev
)
if
(
!
dev
)
...
@@ -1005,6 +1009,7 @@ static int atrtr_ioctl(unsigned int cmd, void *arg)
...
@@ -1005,6 +1009,7 @@ static int atrtr_ioctl(unsigned int cmd, void *arg)
}
}
return
atrtr_create
(
&
rt
,
dev
);
return
atrtr_create
(
&
rt
,
dev
);
}
}
}
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -1159,14 +1164,13 @@ static int atalk_release(struct socket *sock)
...
@@ -1159,14 +1164,13 @@ static int atalk_release(struct socket *sock)
{
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
if
(
!
sk
)
if
(
sk
)
{
goto
out
;
if
(
!
sk
->
dead
)
if
(
!
sk
->
dead
)
sk
->
state_change
(
sk
);
sk
->
state_change
(
sk
);
sk
->
dead
=
1
;
sk
->
dead
=
1
;
sock
->
sk
=
NULL
;
sock
->
sk
=
NULL
;
atalk_destroy_socket
(
sk
);
atalk_destroy_socket
(
sk
);
out:
}
return
0
;
return
0
;
}
}
...
@@ -1222,7 +1226,7 @@ static int atalk_autobind(struct sock *sk)
...
@@ -1222,7 +1226,7 @@ static int atalk_autobind(struct sock *sk)
{
{
struct
atalk_sock
*
at
=
at_sk
(
sk
);
struct
atalk_sock
*
at
=
at_sk
(
sk
);
struct
sockaddr_at
sat
;
struct
sockaddr_at
sat
;
struct
at_addr
*
ap
=
atalk_find_primary
();
struct
at
alk
_addr
*
ap
=
atalk_find_primary
();
int
n
=
-
EADDRNOTAVAIL
;
int
n
=
-
EADDRNOTAVAIL
;
if
(
!
ap
||
ap
->
s_net
==
htons
(
ATADDR_ANYNET
))
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)
...
@@ -1252,7 +1256,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return
-
EAFNOSUPPORT
;
return
-
EAFNOSUPPORT
;
if
(
addr
->
sat_addr
.
s_net
==
htons
(
ATADDR_ANYNET
))
{
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
)
if
(
!
ap
)
return
-
EADDRNOTAVAIL
;
return
-
EADDRNOTAVAIL
;
...
@@ -1330,7 +1334,6 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
...
@@ -1330,7 +1334,6 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
return
0
;
return
0
;
}
}
/*
/*
* Find the name of an AppleTalk socket. Just copy the right
* Find the name of an AppleTalk socket. Just copy the right
* fields into the sockaddr.
* fields into the sockaddr.
...
@@ -1366,6 +1369,124 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
...
@@ -1366,6 +1369,124 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
return
0
;
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
* atalk_rcv - Receive a packet (in skb) from device dev
* @skb - packet received
* @skb - packet received
...
@@ -1381,7 +1502,7 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
...
@@ -1381,7 +1502,7 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
static
int
atalk_rcv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
static
int
atalk_rcv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
)
struct
packet_type
*
pt
)
{
{
struct
ddpehdr
*
ddp
=
(
void
*
)
skb
->
h
.
raw
;
struct
ddpehdr
*
ddp
=
ddp_hdr
(
skb
)
;
struct
sock
*
sock
;
struct
sock
*
sock
;
struct
atalk_iface
*
atif
;
struct
atalk_iface
*
atif
;
struct
sockaddr_at
tosat
;
struct
sockaddr_at
tosat
;
...
@@ -1432,106 +1553,13 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
...
@@ -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 */
/* Not ours, so we route the packet via the correct AppleTalk iface */
if
(
!
atif
)
{
if
(
!
atif
)
{
struct
atalk_route
*
rt
;
atalk_route_packet
(
skb
,
dev
,
ddp
,
&
ddphv
,
origlen
);
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
;
goto
out
;
goto
out
;
}
}
#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE)
/* if IP over DDP is not selected this code will be optimized out */
/* Check if IP-over-DDP */
if
(
is_ip_over_ddp
(
skb
))
if
(
skb
->
data
[
12
]
==
22
)
{
return
handle_ip_over_ddp
(
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. */
goto
out
;
}
#endif
/*
/*
* Which socket - atalk_search_socket() looks for a *full match*
* Which socket - atalk_search_socket() looks for a *full match*
* of the <net, node, port> tuple.
* of the <net, node, port> tuple.
...
@@ -1568,7 +1596,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
...
@@ -1568,7 +1596,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
if
(
skb
->
mac
.
raw
[
2
]
==
1
)
{
if
(
skb
->
mac
.
raw
[
2
]
==
1
)
{
struct
ddpehdr
*
ddp
;
struct
ddpehdr
*
ddp
;
/* Find our address */
/* 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
))
if
(
!
ap
||
skb
->
len
<
sizeof
(
struct
ddpshdr
))
goto
freeit
;
goto
freeit
;
...
@@ -1674,7 +1702,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len,
...
@@ -1674,7 +1702,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len,
dev
=
rt
->
dev
;
dev
=
rt
->
dev
;
}
else
{
}
else
{
struct
at_addr
at_hint
;
struct
at
alk
_addr
at_hint
;
at_hint
.
s_node
=
0
;
at_hint
.
s_node
=
0
;
at_hint
.
s_net
=
at
->
src_net
;
at_hint
.
s_net
=
at
->
src_net
;
...
@@ -1792,7 +1820,7 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size,
...
@@ -1792,7 +1820,7 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size,
return
err
;
return
err
;
/* FIXME: use skb->cb to be able to use shared skbs */
/* 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
));
*
((
__u16
*
)
&
ddphv
)
=
ntohs
(
*
((
__u16
*
)
ddp
));
if
(
sk
->
type
==
SOCK_RAW
)
{
if
(
sk
->
type
==
SOCK_RAW
)
{
...
@@ -1833,40 +1861,48 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size,
...
@@ -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
)
static
int
atalk_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
{
long
amount
=
0
;
int
rc
=
-
EINVAL
;
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
switch
(
cmd
)
{
switch
(
cmd
)
{
/* Protocol layer */
/* Protocol layer */
case
TIOCOUTQ
:
case
TIOCOUTQ
:
{
amount
=
sk
->
sndbuf
-
atomic_read
(
&
sk
->
wmem_alloc
);
long
amount
=
sk
->
sndbuf
-
atomic_read
(
&
sk
->
wmem_alloc
);
if
(
amount
<
0
)
if
(
amount
<
0
)
amount
=
0
;
amount
=
0
;
rc
=
put_user
(
amount
,
(
int
*
)
arg
);
break
;
break
;
}
case
TIOCINQ
:
{
case
TIOCINQ
:
{
/*
/*
* These two are safe on a single CPU system as only
* These two are safe on a single CPU system as only
* user tasks fiddle here
* user tasks fiddle here
*/
*/
struct
sk_buff
*
skb
=
skb_peek
(
&
sk
->
receive_queue
);
struct
sk_buff
*
skb
=
skb_peek
(
&
sk
->
receive_queue
);
long
amount
=
0
;
if
(
skb
)
if
(
skb
)
amount
=
skb
->
len
-
sizeof
(
struct
ddpehdr
);
amount
=
skb
->
len
-
sizeof
(
struct
ddpehdr
);
rc
=
put_user
(
amount
,
(
int
*
)
arg
);
break
;
break
;
}
}
case
SIOCGSTAMP
:
case
SIOCGSTAMP
:
if
(
!
sk
)
if
(
!
sk
)
return
-
EINVAL
;
break
;
rc
=
-
ENOENT
;
if
(
!
sk
->
stamp
.
tv_sec
)
if
(
!
sk
->
stamp
.
tv_sec
)
return
-
ENOENT
;
break
;
r
eturn
copy_to_user
((
void
*
)
arg
,
&
sk
->
stamp
,
r
c
=
copy_to_user
((
void
*
)
arg
,
&
sk
->
stamp
,
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
break
;
/* Routing */
/* Routing */
case
SIOCADDRT
:
case
SIOCADDRT
:
case
SIOCDELRT
:
case
SIOCDELRT
:
if
(
!
capable
(
CAP_NET_ADMIN
))
rc
=
-
EPERM
;
return
-
EPERM
;
if
(
capable
(
CAP_NET_ADMIN
))
return
atrtr_ioctl
(
cmd
,
(
void
*
)
arg
);
rc
=
atrtr_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
/* Interface */
/* Interface */
case
SIOCGIFADDR
:
case
SIOCGIFADDR
:
case
SIOCSIFADDR
:
case
SIOCSIFADDR
:
...
@@ -1874,15 +1910,11 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
...
@@ -1874,15 +1910,11 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case
SIOCATALKDIFADDR
:
case
SIOCATALKDIFADDR
:
case
SIOCDIFADDR
:
case
SIOCDIFADDR
:
case
SIOCSARP
:
/* proxy AARP */
case
SIOCSARP
:
/* proxy AARP */
case
SIOCDARP
:
{
/* proxy AARP */
case
SIOCDARP
:
/* proxy AARP */
int
ret
;
rtnl_lock
();
rtnl_lock
();
r
et
=
atif_ioctl
(
cmd
,
(
void
*
)
arg
);
r
c
=
atif_ioctl
(
cmd
,
(
void
*
)
arg
);
rtnl_unlock
();
rtnl_unlock
();
break
;
return
ret
;
}
/* Physical layer ioctl calls */
/* Physical layer ioctl calls */
case
SIOCSIFLINK
:
case
SIOCSIFLINK
:
case
SIOCGIFHWADDR
:
case
SIOCGIFHWADDR
:
...
@@ -1896,21 +1928,11 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
...
@@ -1896,21 +1928,11 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case
SIOCGIFCOUNT
:
case
SIOCGIFCOUNT
:
case
SIOCGIFINDEX
:
case
SIOCGIFINDEX
:
case
SIOCGIFNAME
:
case
SIOCGIFNAME
:
return
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
rc
=
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
case
SIOCSIFMETRIC
:
break
;
case
SIOCSIFBRDADDR
:
case
SIOCGIFNETMASK
:
case
SIOCSIFNETMASK
:
case
SIOCGIFMEM
:
case
SIOCSIFMEM
:
case
SIOCGIFDSTADDR
:
case
SIOCSIFDSTADDR
:
return
-
EINVAL
;
default:
return
-
EINVAL
;
}
}
return
put_user
(
amount
,
(
int
*
)
arg
)
;
return
rc
;
}
}
static
struct
net_proto_family
atalk_family_ops
=
{
static
struct
net_proto_family
atalk_family_ops
=
{
...
@@ -1955,7 +1977,7 @@ struct packet_type ppptalk_packet_type = {
...
@@ -1955,7 +1977,7 @@ struct packet_type ppptalk_packet_type = {
.
func
=
atalk_rcv
,
.
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 symbols for use by drivers when AppleTalk is a module */
EXPORT_SYMBOL
(
aarp_send_ddp
);
EXPORT_SYMBOL
(
aarp_send_ddp
);
...
@@ -2023,4 +2045,3 @@ static void __exit atalk_exit(void)
...
@@ -2023,4 +2045,3 @@ static void __exit atalk_exit(void)
}
}
module_exit
(
atalk_exit
);
module_exit
(
atalk_exit
);
#endif
/* MODULE */
#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