Merge pull request #94 from rickyzhang82/pr-sheep-net-bug-fix

Fixed show stopper bug in sheep_net module.
This commit is contained in:
asvitkine 2016-08-19 06:16:53 -07:00 committed by GitHub
commit ad270e5a84
2 changed files with 72 additions and 4 deletions

View File

@ -0,0 +1,47 @@
# What
sheep_net is a character virtual device that bridge between BasiliskII and Physical Ethernet card(P)
Here is logical diagram:
Guest Mac OS in emulation (G) <==> Basilisk II (B) <==> /dev/sheep_net (S) <==> Physical Ethernet card on host (P)
sheep_net module masquerade and de-masquerade MAC address on Ethernet frame so that Guest OS and host share the same MAC address with different IP.
See details in [IP aliasing](https://en.wikipedia.org/wiki/IP_aliasing)
# How
## How it works
Sample Setting:
Guest Mac OS IP: 192.168.2.2, Fake MAC address: 84:38:35:5e:c5:5b
Host OS Physical Ethernet car IP: 192.168.2.3, physical MAC address: 84:38:35:5e:c5:5a
From outside, we see 192.168.2.2 and 192.168.2.3 share the same physical MAC address: 84:38:35:5e:c5:5a
From insides, sheep_net module masquerade and de-masquerade MAC address of Ethernet packet between Basilisk and
```
B ==> S ==> P: de-masquerade MAC, convert Fake to Physical
B <== S <== P: masquerade MAC, convert Physical to Fake
```
## How to compile
```
cd Linux/NetDriver
make
//create sheep_net device node
sudo make dev
sudo chown [user account] /dev/sheep_net
sudo make install
sudo modprobe sheep_net
```
## How to use
1. Disable IP forwarding on host (Recommended: By disabling it, guest OS won't receive duplicate IP packet from host again.)
2. Disable firewall on host (Recommended: host may send ICMP host unreachable to gateway. Or you can disable ICMP sending from host by changing iptables.)
3. sudo modprobe sheep_net
4. sudo chown [user account] /dev/sheep_net
5. Launch BasiliskII, choose your physical Ethernet card interface in network tab

View File

@ -223,7 +223,7 @@ int init_module(void)
/* Register driver */
ret = misc_register(&sheep_net_device);
D(bug("Sheep net driver installed\n"));
printk("sheep net: driver installed\n");
return ret;
}
@ -236,7 +236,7 @@ void cleanup_module(void)
{
/* Unregister driver */
misc_deregister(&sheep_net_device);
D(bug("Sheep net driver removed\n"));
printk("sheep net: driver removed\n");
}
@ -500,7 +500,8 @@ static ssize_t sheep_net_write(struct file *f, const char *buf, size_t count, lo
netif_rx(skb);
return count;
}
if (skb->data[0] & ETH_ADDR_MULTICAST) {
/* Relay multicast for host process except ARP packet */
if ((skb->data[0] & ETH_ADDR_MULTICAST) && (eth_hdr(skb)->h_proto != htons(ETH_P_ARP))) {
/* We can't clone the skb since we will manipulate the data below */
struct sk_buff *lskb = skb_copy(skb, GFP_ATOMIC);
if (lskb) {
@ -606,6 +607,9 @@ static int sheep_net_ioctl(struct inode *inode, struct file *f, unsigned int cod
}
skt_set_dead(v->skt);
/*initialize ipfilter*/
v->ipfilter = 0;
/* Attach packet handler */
v->pt.type = htons(ETH_P_ALL);
v->pt.dev = v->ether;
@ -746,9 +750,26 @@ static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struc
/* Apply any filters here (if fake is true, then we *know* we want this packet) */
if (!fake) {
if ((skb->protocol == htons(ETH_P_IP))
&& (!v->ipfilter || (ntohl(ipip_hdr(skb)->daddr) != v->ipfilter && !multicast)))
&& (!v->ipfilter || (ntohl(ip_hdr(skb)->daddr) != v->ipfilter && !multicast))) {
#if DEBUG
char source[16];
snprintf(source, 16, "%pI4", &ip_hdr(skb)->saddr);
D(bug("sheep_net: drop incoming IP packet %s for filter %d.%d.%d.%d\n",
source,
(v->ipfilter >> 24) & 0xff, (v->ipfilter >> 16) & 0xff, (v->ipfilter >> 8) & 0xff, v->ipfilter & 0xff));
#endif
goto drop;
}
#if DEBUG
else{
if(!multicast){
char source[16];
snprintf(source, 16, "%pI4", &ip_hdr(skb)->saddr);
D(bug("sheep_net: retain incoming unicast IP packet %s\n", source));
}
}
#endif
}
/* Masquerade (we are typically a clone - best to make a real copy) */
skb2 = skb_copy(skb, GFP_ATOMIC);