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
Kirill Smelkov
linux
Commits
11c4348e
Commit
11c4348e
authored
Oct 06, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPV4]: Fix ipconfig to be PKT_CAN_SHARE_SKB.
parent
ba0c5354
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
98 additions
and
48 deletions
+98
-48
net/ipv4/ipconfig.c
net/ipv4/ipconfig.c
+98
-48
No files found.
net/ipv4/ipconfig.c
View file @
11c4348e
...
@@ -390,6 +390,7 @@ static int ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct pack
...
@@ -390,6 +390,7 @@ static int ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct pack
static
struct
packet_type
rarp_packet_type
__initdata
=
{
static
struct
packet_type
rarp_packet_type
__initdata
=
{
.
type
=
__constant_htons
(
ETH_P_RARP
),
.
type
=
__constant_htons
(
ETH_P_RARP
),
.
func
=
ic_rarp_recv
,
.
func
=
ic_rarp_recv
,
.
data
=
PKT_CAN_SHARE_SKB
,
};
};
static
inline
void
ic_rarp_init
(
void
)
static
inline
void
ic_rarp_init
(
void
)
...
@@ -408,27 +409,21 @@ static inline void ic_rarp_cleanup(void)
...
@@ -408,27 +409,21 @@ static inline void ic_rarp_cleanup(void)
static
int
__init
static
int
__init
ic_rarp_recv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
)
ic_rarp_recv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
)
{
{
struct
arphdr
*
rarp
=
(
struct
arphdr
*
)
skb
->
h
.
raw
;
struct
arphdr
*
rarp
;
unsigned
char
*
rarp_ptr
=
(
unsigned
char
*
)
(
rarp
+
1
)
;
unsigned
char
*
rarp_ptr
;
unsigned
long
sip
,
tip
;
unsigned
long
sip
,
tip
;
unsigned
char
*
sha
,
*
tha
;
/* s for "source", t for "target" */
unsigned
char
*
sha
,
*
tha
;
/* s for "source", t for "target" */
struct
ic_device
*
d
;
struct
ic_device
*
d
;
/* One reply at a time, please. */
if
(
!
pskb_may_pull
(
skb
,
sizeof
(
arphdr
)))
spin_lock
(
&
ic_recv_lock
);
/* If we already have a reply, just drop the packet */
if
(
ic_got_reply
)
goto
drop
;
goto
drop
;
/* Find the ic_device that the packet arrived on */
/* Basic sanity checks can be done without the lock. */
d
=
ic_first_dev
;
rarp
=
(
struct
arphdr
*
)
skb
->
h
.
raw
;
while
(
d
&&
d
->
dev
!=
dev
)
d
=
d
->
next
;
if
(
!
d
)
goto
drop
;
/* should never happen */
/* If this test doesn't pass, it's not IP, or we should ignore it anyway */
/* If this test doesn't pass, it's not IP, or we should
* ignore it anyway.
*/
if
(
rarp
->
ar_hln
!=
dev
->
addr_len
||
dev
->
type
!=
ntohs
(
rarp
->
ar_hrd
))
if
(
rarp
->
ar_hln
!=
dev
->
addr_len
||
dev
->
type
!=
ntohs
(
rarp
->
ar_hrd
))
goto
drop
;
goto
drop
;
...
@@ -440,6 +435,30 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
...
@@ -440,6 +435,30 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
if
(
rarp
->
ar_pro
!=
htons
(
ETH_P_IP
))
if
(
rarp
->
ar_pro
!=
htons
(
ETH_P_IP
))
goto
drop
;
goto
drop
;
if
(
!
pskb_may_pull
(
skb
,
sizeof
(
arphdr
)
+
(
2
*
dev
->
addr_len
)
+
(
2
*
4
)))
goto
drop
;
/* OK, it is all there and looks valid, process... */
rarp
=
(
struct
arphdr
*
)
skb
->
h
.
raw
;
rarp_ptr
=
(
unsigned
char
*
)
(
rarp
+
1
);
/* One reply at a time, please. */
spin_lock
(
&
ic_recv_lock
);
/* If we already have a reply, just drop the packet */
if
(
ic_got_reply
)
goto
drop_unlock
;
/* Find the ic_device that the packet arrived on */
d
=
ic_first_dev
;
while
(
d
&&
d
->
dev
!=
dev
)
d
=
d
->
next
;
if
(
!
d
)
goto
drop_unlock
;
/* should never happen */
/* Extract variable-width fields */
/* Extract variable-width fields */
sha
=
rarp_ptr
;
sha
=
rarp_ptr
;
rarp_ptr
+=
dev
->
addr_len
;
rarp_ptr
+=
dev
->
addr_len
;
...
@@ -451,11 +470,11 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
...
@@ -451,11 +470,11 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
/* Discard packets which are not meant for us. */
/* Discard packets which are not meant for us. */
if
(
memcmp
(
tha
,
dev
->
dev_addr
,
dev
->
addr_len
))
if
(
memcmp
(
tha
,
dev
->
dev_addr
,
dev
->
addr_len
))
goto
drop
;
goto
drop
_unlock
;
/* Discard packets which are not from specified server. */
/* Discard packets which are not from specified server. */
if
(
ic_servaddr
!=
INADDR_NONE
&&
ic_servaddr
!=
sip
)
if
(
ic_servaddr
!=
INADDR_NONE
&&
ic_servaddr
!=
sip
)
goto
drop
;
goto
drop
_unlock
;
/* We have a winner! */
/* We have a winner! */
ic_dev
=
dev
;
ic_dev
=
dev
;
...
@@ -464,10 +483,11 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
...
@@ -464,10 +483,11 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
ic_servaddr
=
sip
;
ic_servaddr
=
sip
;
ic_got_reply
=
IC_RARP
;
ic_got_reply
=
IC_RARP
;
drop:
drop
_unlock
:
/* Show's over. Nothing to see here. */
/* Show's over. Nothing to see here. */
spin_unlock
(
&
ic_recv_lock
);
spin_unlock
(
&
ic_recv_lock
);
drop:
/* Throw the packet out. */
/* Throw the packet out. */
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
0
;
return
0
;
...
@@ -530,6 +550,7 @@ static int ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct pac
...
@@ -530,6 +550,7 @@ static int ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct pac
static
struct
packet_type
bootp_packet_type
__initdata
=
{
static
struct
packet_type
bootp_packet_type
__initdata
=
{
.
type
=
__constant_htons
(
ETH_P_IP
),
.
type
=
__constant_htons
(
ETH_P_IP
),
.
func
=
ic_bootp_recv
,
.
func
=
ic_bootp_recv
,
.
data
=
PKT_CAN_SHARE_SKB
,
};
};
...
@@ -793,51 +814,79 @@ static void __init ic_do_bootp_ext(u8 *ext)
...
@@ -793,51 +814,79 @@ static void __init ic_do_bootp_ext(u8 *ext)
*/
*/
static
int
__init
ic_bootp_recv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
)
static
int
__init
ic_bootp_recv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
)
{
{
struct
bootp_pkt
*
b
=
(
struct
bootp_pkt
*
)
skb
->
nh
.
iph
;
struct
bootp_pkt
*
b
;
struct
iphdr
*
h
=
&
b
->
iph
;
struct
iphdr
*
h
;
struct
ic_device
*
d
;
struct
ic_device
*
d
;
int
len
;
int
len
;
/* Perform verifications before taking the lock. */
if
(
skb
->
pkt_type
==
PACKET_OTHERHOST
)
goto
drop
;
if
(
!
pskb_may_pull
(
skb
,
sizeof
(
struct
iphdr
)
+
sizeof
(
struct
udphdr
)))
goto
drop
;
b
=
(
struct
bootp_pkt
*
)
skb
->
nh
.
iph
;
h
=
&
b
->
iph
;
if
(
h
->
ihl
!=
5
||
h
->
version
!=
4
||
h
->
protocol
!=
IPPROTO_UDP
)
goto
drop
;
/* Fragments are not supported */
if
(
h
->
frag_off
&
htons
(
IP_OFFSET
|
IP_MF
))
{
if
(
net_ratelimit
())
printk
(
KERN_ERR
"DHCP/BOOTP: Ignoring fragmented "
"reply.
\n
"
);
goto
drop
;
}
if
(
skb
->
len
<
ntohs
(
h
->
tot_len
))
goto
drop
;
if
(
ip_fast_csum
((
char
*
)
h
,
h
->
ihl
))
goto
drop
;
if
(
b
->
udph
.
source
!=
htons
(
67
)
||
b
->
udph
.
dest
!=
htons
(
68
))
goto
drop
;
if
(
ntohs
(
h
->
tot_len
)
<
ntohs
(
b
->
udhp
.
len
)
+
sizeof
(
struct
iphdr
))
goto
drop
;
len
=
ntohs
(
b
->
udph
.
len
)
-
sizeof
(
struct
udphdr
);
if
(
len
<
300
)
goto
drop
;
/* Ok the front looks good, make sure we can get at the rest. */
if
(
!
pskb_may_pull
(
skb
,
skb
->
len
))
goto
drop
;
b
=
(
struct
bootp_pkt
*
)
skb
->
nh
.
iph
;
h
=
&
b
->
iph
;
/* One reply at a time, please. */
/* One reply at a time, please. */
spin_lock
(
&
ic_recv_lock
);
spin_lock
(
&
ic_recv_lock
);
/* If we already have a reply, just drop the packet */
/* If we already have a reply, just drop the packet */
if
(
ic_got_reply
)
if
(
ic_got_reply
)
goto
drop
;
goto
drop
_unlock
;
/* Find the ic_device that the packet arrived on */
/* Find the ic_device that the packet arrived on */
d
=
ic_first_dev
;
d
=
ic_first_dev
;
while
(
d
&&
d
->
dev
!=
dev
)
while
(
d
&&
d
->
dev
!=
dev
)
d
=
d
->
next
;
d
=
d
->
next
;
if
(
!
d
)
if
(
!
d
)
goto
drop
;
/* should never happen */
goto
drop_unlock
;
/* should never happen */
/* Check whether it's a BOOTP packet */
if
(
skb
->
pkt_type
==
PACKET_OTHERHOST
||
skb
->
len
<
sizeof
(
struct
udphdr
)
+
sizeof
(
struct
iphdr
)
||
h
->
ihl
!=
5
||
h
->
version
!=
4
||
ip_fast_csum
((
char
*
)
h
,
h
->
ihl
)
!=
0
||
skb
->
len
<
ntohs
(
h
->
tot_len
)
||
h
->
protocol
!=
IPPROTO_UDP
||
b
->
udph
.
source
!=
htons
(
67
)
||
b
->
udph
.
dest
!=
htons
(
68
)
||
ntohs
(
h
->
tot_len
)
<
ntohs
(
b
->
udph
.
len
)
+
sizeof
(
struct
iphdr
))
goto
drop
;
/* Fragments are not supported */
if
(
h
->
frag_off
&
htons
(
IP_OFFSET
|
IP_MF
))
{
printk
(
KERN_ERR
"DHCP/BOOTP: Ignoring fragmented reply.
\n
"
);
goto
drop
;
}
/* Is it a reply to our BOOTP request? */
/* Is it a reply to our BOOTP request? */
len
=
ntohs
(
b
->
udph
.
len
)
-
sizeof
(
struct
udphdr
);
if
(
b
->
op
!=
BOOTP_REPLY
||
if
(
len
<
300
||
/* See RFC 951:2.1 */
b
->
op
!=
BOOTP_REPLY
||
b
->
xid
!=
d
->
xid
)
{
b
->
xid
!=
d
->
xid
)
{
printk
(
"?"
);
if
(
net_ratelimit
())
goto
drop
;
printk
(
KERN_ERR
"DHCP/BOOTP: Reply not for us, "
"op[%x] xid[%x]
\n
"
,
b
->
op
,
b
->
xid
);
goto
drop_unlock
;
}
}
/* Parse extensions */
/* Parse extensions */
...
@@ -880,7 +929,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
...
@@ -880,7 +929,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
* ignore all others.
* ignore all others.
*/
*/
if
(
ic_myaddr
!=
INADDR_NONE
)
if
(
ic_myaddr
!=
INADDR_NONE
)
goto
drop
;
goto
drop
_unlock
;
/* Let's accept that offer. */
/* Let's accept that offer. */
ic_myaddr
=
b
->
your_ip
;
ic_myaddr
=
b
->
your_ip
;
...
@@ -908,7 +957,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
...
@@ -908,7 +957,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
/* Urque. Forget it*/
/* Urque. Forget it*/
ic_myaddr
=
INADDR_NONE
;
ic_myaddr
=
INADDR_NONE
;
ic_servaddr
=
INADDR_NONE
;
ic_servaddr
=
INADDR_NONE
;
goto
drop
;
goto
drop
_unlock
;
};
};
ic_dhcp_msgtype
=
mt
;
ic_dhcp_msgtype
=
mt
;
...
@@ -937,10 +986,11 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
...
@@ -937,10 +986,11 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
ic_nameservers
[
0
]
=
ic_servaddr
;
ic_nameservers
[
0
]
=
ic_servaddr
;
ic_got_reply
=
IC_BOOTP
;
ic_got_reply
=
IC_BOOTP
;
drop:
drop
_unlock
:
/* Show's over. Nothing to see here. */
/* Show's over. Nothing to see here. */
spin_unlock
(
&
ic_recv_lock
);
spin_unlock
(
&
ic_recv_lock
);
drop:
/* Throw the packet out. */
/* Throw the packet out. */
kfree_skb
(
skb
);
kfree_skb
(
skb
);
...
...
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