From 757b781f309f32c55f1eb0626f2010f5929aaa92 Mon Sep 17 00:00:00 2001 From: xking Date: Sun, 1 Dec 2024 23:06:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BB=84=E6=92=AD=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E6=8E=A5=E6=94=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/cn/x47/RIPService.java | 8 +++- src/main/java/cn/x47/config/Config.java | 4 +- .../java/cn/x47/handle/RIPPacketDecoder.java | 10 +++++ .../java/cn/x47/handle/RIPServerHandler.java | 1 - src/main/java/cn/x47/service/RIPServer.java | 44 ++++++++++++++++++- 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/main/java/cn/x47/RIPService.java b/src/main/java/cn/x47/RIPService.java index c67743a..3ea207d 100644 --- a/src/main/java/cn/x47/RIPService.java +++ b/src/main/java/cn/x47/RIPService.java @@ -8,6 +8,8 @@ import cn.x47.service.RIPClient; import cn.x47.service.RIPServer; import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; @@ -25,6 +27,8 @@ public class RIPService { server.start(); } catch (InterruptedException e) { e.printStackTrace(); + } catch (SocketException | UnknownHostException e) { + throw new RuntimeException(e); } }).start(); System.out.println("服务端已经启动"); @@ -52,8 +56,8 @@ public class RIPService { try { // 示例:添加本地路由条目 - InetAddress localAddress = InetAddress.getByName("10.47.54.0"); - InetAddress subnetMask = InetAddress.getByName("255.255.255.0"); + InetAddress localAddress = InetAddress.getByName("10.110.80.52"); + InetAddress subnetMask = InetAddress.getByName("255.255.255.255"); InetAddress nextHop = InetAddress.getByName("0.0.0.0"); RIPEntry entry = new RIPEntry(); diff --git a/src/main/java/cn/x47/config/Config.java b/src/main/java/cn/x47/config/Config.java index e3cddf1..5cc6abb 100644 --- a/src/main/java/cn/x47/config/Config.java +++ b/src/main/java/cn/x47/config/Config.java @@ -2,7 +2,7 @@ package cn.x47.config; public class Config { // 设置协议版本,1 表示 RIP v1,2 表示 RIP v2 - public static final byte RIP_VERSION = 1; + public static final byte RIP_VERSION = 2; public static final boolean startServer = true; - public static final boolean startClient = false; + public static final boolean startClient = true; } diff --git a/src/main/java/cn/x47/handle/RIPPacketDecoder.java b/src/main/java/cn/x47/handle/RIPPacketDecoder.java index 0d73c6a..3a008f0 100644 --- a/src/main/java/cn/x47/handle/RIPPacketDecoder.java +++ b/src/main/java/cn/x47/handle/RIPPacketDecoder.java @@ -4,12 +4,14 @@ package cn.x47.handle; import cn.x47.model.RIPEntry; import cn.x47.model.RIPPacket; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.socket.DatagramPacket; import io.netty.handler.codec.MessageToMessageDecoder; import java.net.InetAddress; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -42,8 +44,16 @@ public class RIPPacketDecoder extends MessageToMessageDecoder { if (ripPacket.getVersion() == 1) { // 对于 RIP v1,子网掩码和下一跳需要推断或设为默认值 entry.setSubnetMask(InetAddress.getByName("255.255.255.0")); // 示例,实际应根据 IP 类推断 + + } + + byte[] address = entry.getNextHop().getAddress(); + byte[] address1 = InetAddress.getByName("0.0.0.0").getAddress(); + + if(Arrays.equals(address, address1)) { entry.setNextHop(packet.sender().getAddress()); } + entry.setMetric((int) buf.readUnsignedInt()); entries.add(entry); } diff --git a/src/main/java/cn/x47/handle/RIPServerHandler.java b/src/main/java/cn/x47/handle/RIPServerHandler.java index 8ddbe6d..dce5a32 100644 --- a/src/main/java/cn/x47/handle/RIPServerHandler.java +++ b/src/main/java/cn/x47/handle/RIPServerHandler.java @@ -11,7 +11,6 @@ public class RIPServerHandler extends SimpleChannelInboundHandler { @Override protected void channelRead0(ChannelHandlerContext ctx, RIPPacket msg) throws Exception { - System.out.println(msg); if (msg.getCommand() == 2) { // Response for (RIPEntry entry : msg.getEntries()) { // 更新本地路由表 diff --git a/src/main/java/cn/x47/service/RIPServer.java b/src/main/java/cn/x47/service/RIPServer.java index ccab745..d6f84b3 100644 --- a/src/main/java/cn/x47/service/RIPServer.java +++ b/src/main/java/cn/x47/service/RIPServer.java @@ -11,26 +11,68 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.DatagramChannel; import io.netty.channel.socket.nio.NioDatagramChannel; +import java.net.*; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + public class RIPServer { - public void start() throws InterruptedException { + public void start() throws InterruptedException, UnknownHostException, SocketException { NioEventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioDatagramChannel.class) .option(ChannelOption.SO_BROADCAST, true) + .option(ChannelOption.IP_MULTICAST_LOOP_DISABLED, true) .handler(new ChannelInitializer() { @Override protected void initChannel(DatagramChannel ch) throws Exception { + ch.pipeline().addLast(new RIPPacketDecoder(), new RIPServerHandler()); } }); ChannelFuture future = b.bind(520).sync(); + // 获取并加入组播组 + NioDatagramChannel channel = (NioDatagramChannel) future.channel(); + InetAddress multicastAddress = InetAddress.getByName("224.0.0.9"); // 替换为你的组播地址 + + // 自动获取网络接口并加入组播组 + List multicastInterfaces = getMulticastInterfaces(); + for (NetworkInterface networkInterface : multicastInterfaces) { + channel.joinGroup(new InetSocketAddress(multicastAddress, 520), networkInterface).sync(); + System.out.println("已在接口 " + networkInterface.getName() + " 上加入组播组"); + } + System.out.println("监听器已启动,正在监听端口:" + 520); future.channel().closeFuture().await(); } finally { group.shutdownGracefully(); } } + + private List getMulticastInterfaces() throws SocketException { + List interfaces = new ArrayList<>(); + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface networkInterface = networkInterfaces.nextElement(); + if (networkInterface.isUp() && !networkInterface.isLoopback() && networkInterface.supportsMulticast()) { + // 检查是否有 IPv4 地址 + Enumeration addresses = networkInterface.getInetAddresses(); + boolean hasIPv4 = false; + while (addresses.hasMoreElements()) { + InetAddress address = addresses.nextElement(); + if (address instanceof Inet4Address) { + hasIPv4 = true; + break; + } + } + if (hasIPv4) { + interfaces.add(networkInterface); + } + } + } + return interfaces; + } }