mirror of
https://github.com/lucheng0127/virtuallan.git
synced 2025-12-24 13:17:50 +08:00
Support build windows client. Use in windows, make sure you have been install tap-windows properly. After launch, the windows client will now listen udp multicast so if you need to config routes by yourself
88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package packet
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"net"
|
|
|
|
"github.com/lucheng0127/virtuallan/pkg/utils"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const (
|
|
MULTICAST_ADDR = "224.0.0.1"
|
|
MULTICAST_PORT = 9999
|
|
MAX_DATA_SIZE = 8192
|
|
|
|
ROUTES_PREFIX = uint16(0x2b00 | 0x01)
|
|
)
|
|
|
|
func MulticastStream(data []byte) error {
|
|
udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", MULTICAST_ADDR, MULTICAST_PORT))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
conn, err := net.DialUDP("udp", nil, udpAddr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := conn.Write(data); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func MonitorRouteMulticast(iface *net.Interface, tapIP string) {
|
|
// Monitor route multicast will run as a goruntine in client so log error but don't exit
|
|
udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", MULTICAST_ADDR, MULTICAST_PORT))
|
|
if err != nil {
|
|
log.Errorf("parse multicast addr %s", err.Error())
|
|
return
|
|
}
|
|
|
|
// Listen multicast on tap interface
|
|
ln, err := net.ListenMulticastUDP("udp", iface, udpAddr)
|
|
if err != nil {
|
|
log.Errorf("listen multicast address %s", err.Error())
|
|
return
|
|
}
|
|
|
|
// Read data from udp
|
|
for {
|
|
buf := make([]byte, MAX_DATA_SIZE)
|
|
|
|
n, srcAddr, err := ln.ReadFromUDP(buf)
|
|
if err != nil {
|
|
log.Errorf("read from multicast %s", err.Error())
|
|
continue
|
|
}
|
|
|
|
log.Debugf("read multicast from %s", srcAddr.String())
|
|
// XXX: Check source addr same cidr with enpoint ip maybe
|
|
|
|
// Strip route prefix
|
|
if n < 2 {
|
|
// Not validate stream
|
|
continue
|
|
}
|
|
|
|
streamPrefix := binary.BigEndian.Uint16(buf[:2])
|
|
if streamPrefix != ROUTES_PREFIX {
|
|
// Not route stream
|
|
continue
|
|
}
|
|
|
|
// Parse route stream
|
|
routes := utils.ParseRoutesStream(buf[2:])
|
|
log.Debugf("receive route multicast:\n%+v", routes)
|
|
|
|
// Sync routes, use flag replace, for unknow ip need delete
|
|
if err := utils.SyncRoutesForIface(iface.Name, tapIP, routes); err != nil {
|
|
log.Errorf("sync route for %s %s", iface.Name, err.Error())
|
|
}
|
|
}
|
|
}
|