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
5d61c168
Commit
5d61c168
authored
Nov 17, 2002
by
Jeff Dike
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merged the network fixes from the 2.4 pool.
parent
5be2bc3c
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
258 additions
and
135 deletions
+258
-135
arch/um/Kconfig_net
arch/um/Kconfig_net
+147
-0
arch/um/drivers/net_kern.c
arch/um/drivers/net_kern.c
+65
-46
arch/um/drivers/slip.h
arch/um/drivers/slip.h
+6
-4
arch/um/drivers/slip_kern.c
arch/um/drivers/slip_kern.c
+4
-5
arch/um/drivers/slip_user.c
arch/um/drivers/slip_user.c
+26
-80
arch/um/include/net_kern.h
arch/um/include/net_kern.h
+5
-0
arch/um/include/net_user.h
arch/um/include/net_user.h
+5
-0
No files found.
arch/um/Kconfig_net
View file @
5d61c168
...
@@ -5,30 +5,177 @@ menu "Network Devices"
...
@@ -5,30 +5,177 @@ menu "Network Devices"
# UML virtual driver
# UML virtual driver
config UML_NET
config UML_NET
bool "Virtual network device"
bool "Virtual network device"
help
While the User-Mode port cannot directly talk to any physical
hardware devices, this choice and the following transport options
provide one or more virtual network devices through which the UML
kernels can talk to each other, the host, and with the host's help,
machines on the outside world.
For more information, including explanations of the networking and
sample configurations, see
<http://user-mode-linux.sourceforge.net/networking.html>.
If you'd like to be able to enable networking in the User-Mode
linux environment, say Y; otherwise say N. Note that you must
enable at least one of the following transport options to actually
make use of UML networking.
config UML_NET_ETHERTAP
config UML_NET_ETHERTAP
bool "Ethertap transport"
bool "Ethertap transport"
depends on UML_NET
depends on UML_NET
help
The Ethertap User-Mode Linux network transport allows a single
running UML to exchange packets with its host over one of the
host's Ethertap devices, such as /dev/tap0. Additional running
UMLs can use additional Ethertap devices, one per running UML.
While the UML believes it's on a (multi-device, broadcast) virtual
Ethernet network, it's in fact communicating over a point-to-point
link with the host.
To use this, your host kernel must have support for Ethertap
devices. Also, if your host kernel is 2.4.x, it must have
CONFIG_NETLINK_DEV configured as Y or M.
For more information, see
<http://user-mode-linux.sourceforge.net/networking.html> That site
has examples of the UML command line to use to enable Ethertap
networking.
If you'd like to set up an IP network with the host and/or the
outside world, say Y to this, the Daemon Transport and/or the
Slip Transport. You'll need at least one of them, but may choose
more than one without conflict. If you don't need UML networking,
say N.
config UML_NET_TUNTAP
config UML_NET_TUNTAP
bool "TUN/TAP transport"
bool "TUN/TAP transport"
depends on UML_NET
depends on UML_NET
help
The UML TUN/TAP network transport allows a UML instance to exchange
packets with the host over a TUN/TAP device. This option will only
work with a 2.4 host, unless you've applied the TUN/TAP patch to
your 2.2 host kernel.
To use this transport, your host kernel must have support for TUN/TAP
devices, either built-in or as a module.
config UML_NET_SLIP
config UML_NET_SLIP
bool "SLIP transport"
bool "SLIP transport"
depends on UML_NET
depends on UML_NET
help
The slip User-Mode Linux network transport allows a running UML to
network with its host over a point-to-point link. Unlike Ethertap,
which can carry any Ethernet frame (and hence even non-IP packets),
the slip transport can only carry IP packets.
To use this, your host must support slip devices.
For more information, see
<http://user-mode-linux.sourceforge.net/networking.html>. That site
has examples of the UML command line to use to enable slip
networking, and details of a few quirks with it.
The Ethertap Transport is preferred over slip because of its
limitations. If you prefer slip, however, say Y here. Otherwise
choose the Multicast transport (to network multiple UMLs on
multiple hosts), Ethertap (to network with the host and the
outside world), and/or the Daemon transport (to network multiple
UMLs on a single host). You may choose more than one without
conflict. If you don't need UML networking, say N.
config UML_NET_DAEMON
config UML_NET_DAEMON
bool "Daemon transport"
bool "Daemon transport"
depends on UML_NET
depends on UML_NET
help
This User-Mode Linux network transport allows one or more running
UMLs on a single host to communicate with each other, but not to
the host.
To use this form of networking, you'll need to run the UML
networking daemon on the host.
For more information, see
<http://user-mode-linux.sourceforge.net/networking.html> That site
has examples of the UML command line to use to enable Daemon
networking.
If you'd like to set up a network with other UMLs on a single host,
say Y. If you need a network between UMLs on multiple physical
hosts, choose the Multicast Transport. To set up a network with
the host and/or other IP machines, say Y to the Ethertap or Slip
transports. You'll need at least one of them, but may choose
more than one without conflict. If you don't need UML networking,
say N.
config UML_NET_MCAST
config UML_NET_MCAST
bool "Multicast transport"
bool "Multicast transport"
depends on UML_NET
depends on UML_NET
help
This Multicast User-Mode Linux network transport allows multiple
UMLs (even ones running on different host machines!) to talk to
each other over a virtual ethernet network. However, it requires
at least one UML with one of the other transports to act as a
bridge if any of them need to be able to talk to their hosts or any
other IP machines.
To use this, your host kernel(s) must support IP Multicasting.
For more information, see
<http://user-mode-linux.sourceforge.net/networking.html> That site
has examples of the UML command line to use to enable Multicast
networking, and notes about the security of this approach.
If you need UMLs on multiple physical hosts to communicate as if
they shared an Ethernet network, say Y. If you need to communicate
with other IP machines, make sure you select one of the other
transports (possibly in addition to Multicast; they're not
exclusive). If you don't need to network UMLs say N to each of
the transports.
config UML_NET_PCAP
config UML_NET_PCAP
bool "pcap transport"
bool "pcap transport"
depends on UML_NET
depends on UML_NET
help
The pcap transport makes a pcap packet stream on the host look
like an ethernet device inside UML. This is useful for making
UML act as a network monitor for the host. You must have libcap
installed in order to build the pcap transport into UML.
For more information, see
<http://user-mode-linux.sourceforge.net/networking.html> That site
has examples of the UML command line to use to enable this option.
If you intend to use UML as a network monitor for the host, say
Y here. Otherwise, say N.
config UML_NET_SLIRP
bool "SLiRP transport"
depends on UML_NET
help
The SLiRP User-Mode Linux network transport allows a running UML
to network by invoking a program that can handle SLIP encapsulated
packets. This is commonly (but not limited to) the application
known as SLiRP, a program that can re-socket IP packets back onto
the host on which it is run. Only IP packets are supported,
unlike other network transports that can handle all Ethernet
frames. In general, slirp allows the UML the same IP connectivity
to the outside world that the host user is permitted, and unlike
other transports, SLiRP works without the need of root level
privleges, setuid binaries, or SLIP devices on the host. This
also means not every type of connection is possible, but most
situations can be accomodated with carefully crafted slirp
commands that can be passed along as part of the network device's
setup string. The effect of this transport on the UML is similar
that of a host behind a firewall that masquerades all network
connections passing through it (but is less secure).
To use this you should first have slirp compiled somewhere
accessible on the host, and have read its documentation. If you
don't need UML networking, say N.
Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
# Below are hardware-independent drivers mirrored from
# Below are hardware-independent drivers mirrored from
# drivers/net/Config.in. It would be nice if Linux
# drivers/net/Config.in. It would be nice if Linux
...
...
arch/um/drivers/net_kern.c
View file @
5d61c168
...
@@ -39,7 +39,6 @@ static int uml_net_rx(struct net_device *dev)
...
@@ -39,7 +39,6 @@ static int uml_net_rx(struct net_device *dev)
/* If we can't allocate memory, try again next round. */
/* If we can't allocate memory, try again next round. */
if
((
skb
=
dev_alloc_skb
(
dev
->
mtu
))
==
NULL
)
{
if
((
skb
=
dev_alloc_skb
(
dev
->
mtu
))
==
NULL
)
{
lp
->
stats
.
rx_dropped
++
;
lp
->
stats
.
rx_dropped
++
;
reactivate_fd
(
lp
->
fd
,
UM_ETH_IRQ
);
return
0
;
return
0
;
}
}
...
@@ -48,7 +47,6 @@ static int uml_net_rx(struct net_device *dev)
...
@@ -48,7 +47,6 @@ static int uml_net_rx(struct net_device *dev)
skb
->
mac
.
raw
=
skb
->
data
;
skb
->
mac
.
raw
=
skb
->
data
;
pkt_len
=
(
*
lp
->
read
)(
lp
->
fd
,
&
skb
,
lp
);
pkt_len
=
(
*
lp
->
read
)(
lp
->
fd
,
&
skb
,
lp
);
reactivate_fd
(
lp
->
fd
,
UM_ETH_IRQ
);
if
(
pkt_len
>
0
)
{
if
(
pkt_len
>
0
)
{
skb_trim
(
skb
,
pkt_len
);
skb_trim
(
skb
,
pkt_len
);
skb
->
protocol
=
(
*
lp
->
protocol
)(
skb
);
skb
->
protocol
=
(
*
lp
->
protocol
)(
skb
);
...
@@ -69,18 +67,22 @@ void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -69,18 +67,22 @@ void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct
uml_net_private
*
lp
=
dev
->
priv
;
struct
uml_net_private
*
lp
=
dev
->
priv
;
int
err
;
int
err
;
if
(
netif_running
(
dev
))
{
if
(
!
netif_running
(
dev
))
spin_lock
(
&
lp
->
lock
)
;
return
;
while
((
err
=
uml_net_rx
(
dev
))
>
0
)
;
if
(
err
<
0
)
{
spin_lock
(
&
lp
->
lock
);
printk
(
KERN_ERR
while
((
err
=
uml_net_rx
(
dev
))
>
0
)
;
"Device '%s' read returned %d, shutting it "
if
(
err
<
0
)
{
"down
\n
"
,
dev
->
name
,
err
);
printk
(
KERN_ERR
dev
->
flags
&=
~
IFF_UP
;
"Device '%s' read returned %d, shutting it down
\n
"
,
dev_close
(
dev
);
dev
->
name
,
err
);
}
dev_close
(
dev
);
spin_unlock
(
&
lp
->
lock
)
;
goto
out
;
}
}
reactivate_fd
(
lp
->
fd
,
UM_ETH_IRQ
);
out:
spin_unlock
(
&
lp
->
lock
);
}
}
static
int
uml_net_open
(
struct
net_device
*
dev
)
static
int
uml_net_open
(
struct
net_device
*
dev
)
...
@@ -250,6 +252,37 @@ void uml_net_user_timer_expire(unsigned long _conn)
...
@@ -250,6 +252,37 @@ void uml_net_user_timer_expire(unsigned long _conn)
#endif
#endif
}
}
/*
* default do nothing hard header packet routines for struct net_device init.
* real ethernet transports will overwrite with real routines.
*/
static
int
uml_net_hard_header
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
unsigned
short
type
,
void
*
daddr
,
void
*
saddr
,
unsigned
len
)
{
return
(
0
);
/* no change */
}
static
int
uml_net_rebuild_header
(
struct
sk_buff
*
skb
)
{
return
(
0
);
/* ignore */
}
static
int
uml_net_header_cache
(
struct
neighbour
*
neigh
,
struct
hh_cache
*
hh
)
{
return
(
-
1
);
/* fail */
}
static
void
uml_net_header_cache_update
(
struct
hh_cache
*
hh
,
struct
net_device
*
dev
,
unsigned
char
*
haddr
)
{
/* ignore */
}
static
int
uml_net_header_parse
(
struct
sk_buff
*
skb
,
unsigned
char
*
haddr
)
{
return
(
0
);
/* nothing */
}
static
spinlock_t
devices_lock
=
SPIN_LOCK_UNLOCKED
;
static
spinlock_t
devices_lock
=
SPIN_LOCK_UNLOCKED
;
static
struct
list_head
devices
=
LIST_HEAD_INIT
(
devices
);
static
struct
list_head
devices
=
LIST_HEAD_INIT
(
devices
);
...
@@ -261,21 +294,25 @@ static int eth_configure(int n, void *init, char *mac,
...
@@ -261,21 +294,25 @@ static int eth_configure(int n, void *init, char *mac,
struct
uml_net_private
*
lp
;
struct
uml_net_private
*
lp
;
int
save
,
err
,
size
;
int
save
,
err
,
size
;
size
=
transport
->
private_size
+
sizeof
(
struct
uml_net_private
)
+
sizeof
(((
struct
uml_net_private
*
)
0
)
->
user
);
device
=
kmalloc
(
sizeof
(
*
device
),
GFP_KERNEL
);
device
=
kmalloc
(
sizeof
(
*
device
),
GFP_KERNEL
);
if
(
device
==
NULL
){
if
(
device
==
NULL
){
printk
(
KERN_ERR
"eth_configure failed to allocate uml_net
\n
"
);
printk
(
KERN_ERR
"eth_configure failed to allocate uml_net
\n
"
);
return
(
1
);
return
(
1
);
}
}
*
device
=
((
struct
uml_net
)
{
.
list
=
LIST_HEAD_INIT
(
device
->
list
),
.
dev
=
NULL
,
.
index
=
n
,
.
mac
=
{
[
0
...
5
]
=
0
},
.
have_mac
=
0
});
spin_lock
(
&
devices_lock
);
spin_lock
(
&
devices_lock
);
list_add
(
&
device
->
list
,
&
devices
);
list_add
(
&
device
->
list
,
&
devices
);
spin_unlock
(
&
devices_lock
);
spin_unlock
(
&
devices_lock
);
device
->
index
=
n
;
size
=
transport
->
private_size
+
sizeof
(
struct
uml_net_private
)
+
sizeof
(((
struct
uml_net_private
*
)
0
)
->
user
);
if
(
setup_etheraddr
(
mac
,
device
->
mac
))
if
(
setup_etheraddr
(
mac
,
device
->
mac
))
device
->
have_mac
=
1
;
device
->
have_mac
=
1
;
...
@@ -290,10 +327,18 @@ static int eth_configure(int n, void *init, char *mac,
...
@@ -290,10 +327,18 @@ static int eth_configure(int n, void *init, char *mac,
printk
(
KERN_ERR
"eth_configure: failed to allocate device
\n
"
);
printk
(
KERN_ERR
"eth_configure: failed to allocate device
\n
"
);
return
(
1
);
return
(
1
);
}
}
memset
(
dev
,
0
,
sizeof
(
*
dev
)
+
size
);
snprintf
(
dev
->
name
,
sizeof
(
dev
->
name
),
"eth%d"
,
n
);
snprintf
(
dev
->
name
,
sizeof
(
dev
->
name
),
"eth%d"
,
n
);
dev
->
priv
=
(
void
*
)
&
dev
[
1
];
dev
->
priv
=
(
void
*
)
&
dev
[
1
];
device
->
dev
=
dev
;
device
->
dev
=
dev
;
dev
->
hard_header
=
uml_net_hard_header
;
dev
->
rebuild_header
=
uml_net_rebuild_header
;
dev
->
hard_header_cache
=
uml_net_header_cache
;
dev
->
header_cache_update
=
uml_net_header_cache_update
;
dev
->
hard_header_parse
=
uml_net_header_parse
;
(
*
transport
->
kern
->
init
)(
dev
,
init
);
(
*
transport
->
kern
->
init
)(
dev
,
init
);
dev
->
mtu
=
transport
->
user
->
max_packet
;
dev
->
mtu
=
transport
->
user
->
max_packet
;
...
@@ -308,32 +353,6 @@ static int eth_configure(int n, void *init, char *mac,
...
@@ -308,32 +353,6 @@ static int eth_configure(int n, void *init, char *mac,
dev
->
do_ioctl
=
uml_net_ioctl
;
dev
->
do_ioctl
=
uml_net_ioctl
;
dev
->
watchdog_timeo
=
(
HZ
>>
1
);
dev
->
watchdog_timeo
=
(
HZ
>>
1
);
dev
->
irq
=
UM_ETH_IRQ
;
dev
->
irq
=
UM_ETH_IRQ
;
dev
->
init
=
NULL
;
dev
->
master
=
NULL
;
dev
->
neigh_setup
=
NULL
;
dev
->
owner
=
NULL
;
dev
->
state
=
0
;
dev
->
next_sched
=
0
;
dev
->
get_wireless_stats
=
0
;
dev
->
wireless_handlers
=
0
;
dev
->
gflags
=
0
;
dev
->
mc_list
=
NULL
;
dev
->
mc_count
=
0
;
dev
->
promiscuity
=
0
;
dev
->
atalk_ptr
=
NULL
;
dev
->
ip_ptr
=
NULL
;
dev
->
dn_ptr
=
NULL
;
dev
->
ip6_ptr
=
NULL
;
dev
->
ec_ptr
=
NULL
;
atomic_set
(
&
dev
->
refcnt
,
0
);
dev
->
features
=
0
;
dev
->
uninit
=
NULL
;
dev
->
destructor
=
NULL
;
dev
->
set_config
=
NULL
;
dev
->
accept_fastpath
=
0
;
dev
->
br_port
=
0
;
dev
->
mem_start
=
0
;
dev
->
mem_end
=
0
;
rtnl_lock
();
rtnl_lock
();
err
=
register_netdevice
(
dev
);
err
=
register_netdevice
(
dev
);
...
@@ -372,6 +391,7 @@ static int eth_configure(int n, void *init, char *mac,
...
@@ -372,6 +391,7 @@ static int eth_configure(int n, void *init, char *mac,
if
(
transport
->
user
->
init
)
if
(
transport
->
user
->
init
)
(
*
transport
->
user
->
init
)(
&
lp
->
user
,
dev
);
(
*
transport
->
user
->
init
)(
&
lp
->
user
,
dev
);
if
(
device
->
have_mac
)
if
(
device
->
have_mac
)
set_ether_mac
(
dev
,
device
->
mac
);
set_ether_mac
(
dev
,
device
->
mac
);
return
(
0
);
return
(
0
);
...
@@ -486,7 +506,6 @@ void register_transport(struct transport *new)
...
@@ -486,7 +506,6 @@ void register_transport(struct transport *new)
kfree
(
init
);
kfree
(
init
);
}
}
list_del
(
&
eth
->
list
);
list_del
(
&
eth
->
list
);
return
;
}
}
}
}
...
@@ -580,7 +599,7 @@ static int net_remove(char *str)
...
@@ -580,7 +599,7 @@ static int net_remove(char *str)
int
n
;
int
n
;
n
=
simple_strtoul
(
str
,
&
end
,
0
);
n
=
simple_strtoul
(
str
,
&
end
,
0
);
if
(
*
end
!=
'\0'
)
if
(
(
*
end
!=
'\0'
)
||
(
end
==
str
)
)
return
(
-
1
);
return
(
-
1
);
device
=
find_device
(
n
);
device
=
find_device
(
n
);
...
...
arch/um/drivers/slip.h
View file @
5d61c168
...
@@ -2,6 +2,9 @@
...
@@ -2,6 +2,9 @@
#define __UM_SLIP_H
#define __UM_SLIP_H
#define BUF_SIZE 1500
#define BUF_SIZE 1500
/* two bytes each for a (pathological) max packet of escaped chars + *
* terminating END char + initial END char */
#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
struct
slip_data
{
struct
slip_data
{
void
*
dev
;
void
*
dev
;
...
@@ -9,10 +12,9 @@ struct slip_data {
...
@@ -9,10 +12,9 @@ struct slip_data {
char
*
addr
;
char
*
addr
;
char
*
gate_addr
;
char
*
gate_addr
;
int
slave
;
int
slave
;
/* two bytes each for a (pathological) max packet of escaped chars +
char
ibuf
[
ENC_BUF_SIZE
];
* terminating END char + inital END char
char
obuf
[
ENC_BUF_SIZE
];
*/
int
more
;
/* more data: do not read fd until ibuf has been drained */
char
buf
[
2
*
BUF_SIZE
+
2
];
int
pos
;
int
pos
;
int
esc
;
int
esc
;
};
};
...
...
arch/um/drivers/slip_kern.c
View file @
5d61c168
#include "linux/config.h"
#include "linux/kernel.h"
#include "linux/kernel.h"
#include "linux/stddef.h"
#include "linux/stddef.h"
#include "linux/init.h"
#include "linux/init.h"
...
@@ -24,21 +25,19 @@ void slip_init(struct net_device *dev, void *data)
...
@@ -24,21 +25,19 @@ void slip_init(struct net_device *dev, void *data)
{
name
:
{
'\0'
},
{
name
:
{
'\0'
},
addr:
NULL
,
addr:
NULL
,
gate_addr
:
init
->
gate_addr
,
gate_addr
:
init
->
gate_addr
,
slave
:
0
,
slave
:
-
1
,
buf
:
{
'\0'
},
ibuf
:
{
'\0'
},
obuf
:
{
'\0'
},
pos
:
0
,
pos
:
0
,
esc
:
0
,
esc
:
0
,
dev
:
dev
});
dev
:
dev
});
strncpy
(
dev
->
name
,
"umn"
,
IFNAMSIZ
);
dev
->
init
=
NULL
;
dev
->
init
=
NULL
;
dev
->
hard_header_len
=
0
;
dev
->
hard_header_len
=
0
;
dev
->
addr_len
=
4
;
dev
->
addr_len
=
4
;
dev
->
type
=
ARPHRD_ETHER
;
dev
->
type
=
ARPHRD_ETHER
;
dev
->
tx_queue_len
=
256
;
dev
->
tx_queue_len
=
256
;
dev
->
flags
=
IFF_NOARP
;
dev
->
flags
=
IFF_NOARP
;
if
(
register_netdev
(
dev
))
printk
(
KERN_ERR
"Couldn't initialize umn
\n
"
);
printk
(
"SLIP backend - SLIP IP = %s
\n
"
,
spri
->
gate_addr
);
printk
(
"SLIP backend - SLIP IP = %s
\n
"
,
spri
->
gate_addr
);
}
}
...
...
arch/um/drivers/slip_user.c
View file @
5d61c168
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include "user.h"
#include "user.h"
#include "net_user.h"
#include "net_user.h"
#include "slip.h"
#include "slip.h"
#include "slip_proto.h"
#include "helper.h"
#include "helper.h"
#include "os.h"
#include "os.h"
...
@@ -66,7 +67,7 @@ static void slip_pre_exec(void *arg)
...
@@ -66,7 +67,7 @@ static void slip_pre_exec(void *arg)
if
(
data
->
stdin
!=
-
1
)
dup2
(
data
->
stdin
,
0
);
if
(
data
->
stdin
!=
-
1
)
dup2
(
data
->
stdin
,
0
);
dup2
(
data
->
stdout
,
1
);
dup2
(
data
->
stdout
,
1
);
close
(
data
->
close_me
);
if
(
data
->
close_me
!=
-
1
)
close
(
data
->
close_me
);
}
}
static
int
slip_tramp
(
char
**
argv
,
int
fd
)
static
int
slip_tramp
(
char
**
argv
,
int
fd
)
...
@@ -156,7 +157,7 @@ static int slip_open(void *data)
...
@@ -156,7 +157,7 @@ static int slip_open(void *data)
}
}
sencap
=
0
;
sencap
=
0
;
if
(
ioctl
(
sfd
,
SIOCSIFENCAP
,
&
sencap
)
<
0
){
if
(
ioctl
(
sfd
,
SIOCSIFENCAP
,
&
sencap
)
<
0
){
printk
(
"Failed to set
t
slip encapsulation - "
printk
(
"Failed to set slip encapsulation - "
"errno = %d
\n
"
,
errno
);
"errno = %d
\n
"
,
errno
);
return
(
-
errno
);
return
(
-
errno
);
}
}
...
@@ -186,103 +187,48 @@ static void slip_close(int fd, void *data)
...
@@ -186,103 +187,48 @@ static void slip_close(int fd, void *data)
pri
->
slave
=
-
1
;
pri
->
slave
=
-
1
;
}
}
/* SLIP protocol characters. */
#define END 0300
/* indicates end of frame */
#define ESC 0333
/* indicates byte stuffing */
#define ESC_END 0334
/* ESC ESC_END means END 'data' */
#define ESC_ESC 0335
/* ESC ESC_ESC means ESC 'data' */
static
int
slip_unesc
(
struct
slip_data
*
sl
,
unsigned
char
c
)
{
int
ret
;
switch
(
c
){
case
END
:
sl
->
esc
=
0
;
ret
=
sl
->
pos
;
sl
->
pos
=
0
;
return
(
ret
);
case
ESC
:
sl
->
esc
=
1
;
return
(
0
);
case
ESC_ESC
:
if
(
sl
->
esc
){
sl
->
esc
=
0
;
c
=
ESC
;
}
break
;
case
ESC_END
:
if
(
sl
->
esc
){
sl
->
esc
=
0
;
c
=
END
;
}
break
;
}
sl
->
buf
[
sl
->
pos
++
]
=
c
;
return
(
0
);
}
int
slip_user_read
(
int
fd
,
void
*
buf
,
int
len
,
struct
slip_data
*
pri
)
int
slip_user_read
(
int
fd
,
void
*
buf
,
int
len
,
struct
slip_data
*
pri
)
{
{
int
i
,
n
,
size
,
start
;
int
i
,
n
,
size
,
start
;
n
=
net_read
(
fd
,
&
pri
->
buf
[
pri
->
pos
],
sizeof
(
pri
->
buf
)
-
pri
->
pos
);
if
(
pri
->
more
>
0
)
{
i
=
0
;
while
(
i
<
pri
->
more
)
{
size
=
slip_unesc
(
pri
->
ibuf
[
i
++
],
pri
->
ibuf
,
&
pri
->
pos
,
&
pri
->
esc
);
if
(
size
){
memcpy
(
buf
,
pri
->
ibuf
,
size
);
memmove
(
pri
->
ibuf
,
&
pri
->
ibuf
[
i
],
pri
->
more
-
i
);
pri
->
more
=
pri
->
more
-
i
;
return
(
size
);
}
}
pri
->
more
=
0
;
}
n
=
net_read
(
fd
,
&
pri
->
ibuf
[
pri
->
pos
],
sizeof
(
pri
->
ibuf
)
-
pri
->
pos
);
if
(
n
<=
0
)
return
(
n
);
if
(
n
<=
0
)
return
(
n
);
start
=
pri
->
pos
;
start
=
pri
->
pos
;
for
(
i
=
0
;
i
<
n
;
i
++
){
for
(
i
=
0
;
i
<
n
;
i
++
){
size
=
slip_unesc
(
pri
,
pri
->
buf
[
start
+
i
]);
size
=
slip_unesc
(
pri
->
ibuf
[
start
+
i
],
pri
->
ibuf
,
&
pri
->
pos
,
&
pri
->
esc
);
if
(
size
){
if
(
size
){
memcpy
(
buf
,
pri
->
buf
,
size
);
memcpy
(
buf
,
pri
->
ibuf
,
size
);
memmove
(
pri
->
ibuf
,
&
pri
->
ibuf
[
start
+
i
+
1
],
n
-
(
i
+
1
));
pri
->
more
=
n
-
(
i
+
1
);
return
(
size
);
return
(
size
);
}
}
}
}
return
(
0
);
return
(
0
);
}
}
static
int
slip_esc
(
unsigned
char
*
s
,
unsigned
char
*
d
,
int
len
)
{
unsigned
char
*
ptr
=
d
;
unsigned
char
c
;
/*
* Send an initial END character to flush out any
* data that may have accumulated in the receiver
* due to line noise.
*/
*
ptr
++
=
END
;
/*
* For each byte in the packet, send the appropriate
* character sequence, according to the SLIP protocol.
*/
while
(
len
--
>
0
)
{
switch
(
c
=
*
s
++
)
{
case
END
:
*
ptr
++
=
ESC
;
*
ptr
++
=
ESC_END
;
break
;
case
ESC
:
*
ptr
++
=
ESC
;
*
ptr
++
=
ESC_ESC
;
break
;
default:
*
ptr
++
=
c
;
break
;
}
}
*
ptr
++
=
END
;
return
(
ptr
-
d
);
}
int
slip_user_write
(
int
fd
,
void
*
buf
,
int
len
,
struct
slip_data
*
pri
)
int
slip_user_write
(
int
fd
,
void
*
buf
,
int
len
,
struct
slip_data
*
pri
)
{
{
int
actual
,
n
;
int
actual
,
n
;
actual
=
slip_esc
(
buf
,
pri
->
buf
,
len
);
actual
=
slip_esc
(
buf
,
pri
->
o
buf
,
len
);
n
=
net_write
(
fd
,
pri
->
buf
,
actual
);
n
=
net_write
(
fd
,
pri
->
o
buf
,
actual
);
if
(
n
<
0
)
return
(
n
);
if
(
n
<
0
)
return
(
n
);
else
return
(
len
);
else
return
(
len
);
}
}
...
...
arch/um/include/net_kern.h
View file @
5d61c168
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __UM_NET_KERN_H
#ifndef __UM_NET_KERN_H
#define __UM_NET_KERN_H
#define __UM_NET_KERN_H
...
...
arch/um/include/net_user.h
View file @
5d61c168
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __UM_NET_USER_H__
#ifndef __UM_NET_USER_H__
#define __UM_NET_USER_H__
#define __UM_NET_USER_H__
...
...
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