diff --git a/src/main/java/cn/x47/handle/RIPPacketDecoder.java b/src/main/java/cn/x47/handle/RIPPacketDecoder.java index 4184cf4..fe90c55 100644 --- a/src/main/java/cn/x47/handle/RIPPacketDecoder.java +++ b/src/main/java/cn/x47/handle/RIPPacketDecoder.java @@ -1,6 +1,5 @@ package cn.x47.handle; - import cn.x47.model.RIPEntry; import cn.x47.model.RIPPacket; import io.netty.buffer.ByteBuf; @@ -28,14 +27,12 @@ public class RIPPacketDecoder extends MessageToMessageDecoder { List entries = new ArrayList<>(); while (buf.readableBytes() >= 20) { RIPEntry entry = new RIPEntry(); - entry.setAddressFamily((short) buf.readUnsignedShort()); - + entry.setAddressFamily(buf.readShort()); if (ripPacket.getVersion() == 2) { - entry.setRouteTag((short) buf.readUnsignedShort()); + entry.setRouteTag(buf.readShort()); } else { entry.setRouteTag((short) 0); } - byte[] ipBytes = new byte[4]; buf.readBytes(ipBytes); entry.setIpAddress(InetAddress.getByAddress(ipBytes)); @@ -50,15 +47,10 @@ public class RIPPacketDecoder extends MessageToMessageDecoder { entry.setSubnetMask(InetAddress.getByName("255.255.255.0")); // 示例,实际应根据 IP 类推断 entry.setNextHop(packet.sender().getAddress()); } - - long metric = buf.readUnsignedInt(); - entry.setMetric(metric); - + entry.setMetric(buf.readInt()); entries.add(entry); } ripPacket.setEntries(entries); - ripPacket.setSenderAddress(packet.sender()); // 设置发送者地址 out.add(ripPacket); } - } diff --git a/src/main/java/cn/x47/handle/RIPPacketEncoder.java b/src/main/java/cn/x47/handle/RIPPacketEncoder.java index c2a5be4..c867a10 100644 --- a/src/main/java/cn/x47/handle/RIPPacketEncoder.java +++ b/src/main/java/cn/x47/handle/RIPPacketEncoder.java @@ -21,22 +21,20 @@ public class RIPPacketEncoder extends MessageToMessageEncoder { // 编码命令和版本 buf.writeByte(msg.getCommand()); buf.writeByte(msg.getVersion()); - buf.writeShort(msg.getUnused()); // unused 字段 + buf.writeShort(0); // unused 字段 // 编码路由条目 for (RIPEntry entry : msg.getEntries()) { - buf.writeShort(entry.getAddressFamily() & 0xFFFF); + buf.writeShort(entry.getAddressFamily()); if (msg.getVersion() == 2) { - buf.writeShort(entry.getRouteTag() & 0xFFFF); + buf.writeShort(entry.getRouteTag()); } buf.writeBytes(entry.getIpAddress().getAddress()); - if (msg.getVersion() == 2) { buf.writeBytes(entry.getSubnetMask().getAddress()); buf.writeBytes(entry.getNextHop().getAddress()); } - - buf.writeInt((int) entry.getMetric() & 0xFFFFFFFF); + buf.writeInt(entry.getMetric()); } // 根据版本选择目标地址 @@ -49,5 +47,4 @@ public class RIPPacketEncoder extends MessageToMessageEncoder { out.add(new DatagramPacket(buf, recipient)); } - } diff --git a/src/main/java/cn/x47/handle/RIPServerHandler.java b/src/main/java/cn/x47/handle/RIPServerHandler.java index 9a8d6b0..242795b 100644 --- a/src/main/java/cn/x47/handle/RIPServerHandler.java +++ b/src/main/java/cn/x47/handle/RIPServerHandler.java @@ -1,185 +1,35 @@ package cn.x47.handle; + import cn.x47.model.RIPEntry; import cn.x47.model.RIPPacket; -import cn.x47.service.RoutingTable; -import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.channel.socket.DatagramPacket; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.List; public class RIPServerHandler extends SimpleChannelInboundHandler { @Override protected void channelRead0(ChannelHandlerContext ctx, RIPPacket msg) throws Exception { - InetSocketAddress senderAddress = msg.getSenderAddress(); - byte version = msg.getVersion(); - System.out.println(msg.toString()); - -// if (msg.getCommand() == 2) { // Response -// for (RIPEntry entry : msg.getEntries()) { -// // 更新本地路由表 -// updateRoutingTable(entry, senderAddress, version); -// } -// } else if (msg.getCommand() == 1) { // Request -// // 处理请求,发送响应包 -// handleRequest(ctx, msg); -// } - } - - private void handleRequest(ChannelHandlerContext ctx, RIPPacket requestPacket) throws Exception { - List requestEntries = requestPacket.getEntries(); - byte version = requestPacket.getVersion(); - - boolean isGeneralRequest = false; - - // 检查是否为一般请求 - if (requestEntries.size() == 1) { - RIPEntry entry = requestEntries.get(0); - if (entry.getIpAddress().getHostAddress().equals("0.0.0.0") && entry.getMetric() == 16) { - isGeneralRequest = true; + System.out.println(msg); + if (msg.getCommand() == 2) { // Response + for (RIPEntry entry : msg.getEntries()) { + // 更新本地路由表 + updateRoutingTable(entry); } - } - - RIPPacket responsePacket = new RIPPacket(); - responsePacket.setCommand((byte) 2); // Response - responsePacket.setVersion(version); // 与请求的版本一致 - responsePacket.setUnused((short) 0); - List responseEntries = new ArrayList<>(); - - if (isGeneralRequest) { - // 一般请求,返回整个路由表 - responseEntries.addAll(getAllRoutingEntries(version)); - } else { - // 特定请求,逐一处理请求的条目 - for (RIPEntry requestEntry : requestEntries) { - RIPEntry route = getRoutingEntry(requestEntry.getIpAddress()); - if (route != null) { - responseEntries.add(route); - } else { - // 如果没有该路由,返回度量值为 16(无限) - RIPEntry unreachableEntry = new RIPEntry(); - unreachableEntry.setAddressFamily(requestEntry.getAddressFamily()); - unreachableEntry.setIpAddress(requestEntry.getIpAddress()); - unreachableEntry.setMetric(16); - - if (version == 2) { - unreachableEntry.setRouteTag((short) 0); - unreachableEntry.setSubnetMask(requestEntry.getSubnetMask()); - unreachableEntry.setNextHop(InetAddress.getByName("0.0.0.0")); - } - - responseEntries.add(unreachableEntry); - } + } else if (msg.getCommand() == 1) { + for (RIPEntry entry : msg.getEntries()) { + // 更新本地路由表 + updateRoutingTable(entry); } - } - - // 构建响应包 - responsePacket.setEntries(responseEntries); - - // 获取发送者的地址 - InetSocketAddress recipient = requestPacket.getSenderAddress(); - - // 发送响应包 - ByteBuf buf = ctx.alloc().buffer().order(ByteOrder.BIG_ENDIAN); // 确保使用大端序 - encodeRIPPacket(responsePacket, buf); - - DatagramPacket responseDatagram = new DatagramPacket(buf, recipient); - ctx.writeAndFlush(responseDatagram); - } - - private void encodeRIPPacket(RIPPacket msg, ByteBuf buf) throws Exception { - // 编码命令和版本 - buf.writeByte(msg.getCommand()); - buf.writeByte(msg.getVersion()); - buf.writeShort(0); // unused 字段 - - // 编码路由条目 - for (RIPEntry entry : msg.getEntries()) { - buf.writeShort(entry.getAddressFamily()); - if (msg.getVersion() == 2) { - buf.writeShort(entry.getRouteTag()); - } - buf.writeBytes(entry.getIpAddress().getAddress()); - - if (msg.getVersion() == 2) { - buf.writeBytes(entry.getSubnetMask().getAddress()); - buf.writeBytes(entry.getNextHop().getAddress()); - } - buf.writeInt((int) (entry.getMetric() & 0xFFFFFFFFL)); + // 处理请求,可能需要发送响应包 + // ... } } - private List getAllRoutingEntries(byte version) throws Exception { - List entries = new ArrayList<>(); - // 从路由表中获取所有的路由条目 - for (RIPEntry route : RoutingTable.getInstance().getRoutes().values()) { - RIPEntry entry = new RIPEntry(); - entry.setAddressFamily(route.getAddressFamily()); - entry.setIpAddress(route.getIpAddress()); - entry.setMetric(route.getMetric()); - - if (version == 2) { - entry.setRouteTag(route.getRouteTag()); - entry.setSubnetMask(route.getSubnetMask()); - entry.setNextHop(route.getNextHop()); - } - - entries.add(entry); - } - return entries; - } - - private RIPEntry getRoutingEntry(InetAddress ipAddress) throws Exception { - RIPEntry route = RoutingTable.getInstance().getRoute(ipAddress); - if (route != null) { - RIPEntry entry = new RIPEntry(); - entry.setAddressFamily(route.getAddressFamily()); - entry.setIpAddress(route.getIpAddress()); - entry.setMetric(route.getMetric()); - - entry.setRouteTag(route.getRouteTag()); - entry.setSubnetMask(route.getSubnetMask()); - entry.setNextHop(route.getNextHop()); - - return entry; - } - return null; - } - - private void updateRoutingTable(RIPEntry entry, InetSocketAddress senderAddress, byte version) throws Exception { - if (version == 1) { - // 推断下一跳为发送者的地址 - entry.setNextHop(senderAddress.getAddress()); - // 根据 IP 地址类别推断子网掩码 - InetAddress ipAddress = entry.getIpAddress(); - byte[] addressBytes = ipAddress.getAddress(); - int firstOctet = addressBytes[0] & 0xFF; - - if (firstOctet >= 0 && firstOctet <= 127) { - // A 类地址 - entry.setSubnetMask(InetAddress.getByName("255.0.0.0")); - } else if (firstOctet >= 128 && firstOctet <= 191) { - // B 类地址 - entry.setSubnetMask(InetAddress.getByName("255.255.0.0")); - } else if (firstOctet >= 192 && firstOctet <= 223) { - // C 类地址 - entry.setSubnetMask(InetAddress.getByName("255.255.255.0")); - } else { - // 非法地址,忽略 - System.out.println("Invalid IP address in RIP Entry: " + ipAddress.getHostAddress()); - return; - } - } + private void updateRoutingTable(RIPEntry entry) { // 实现路由表更新逻辑 - RoutingTable.getInstance().updateRoute(entry); - System.out.println("Updated route: " + entry.getIpAddress().getHostAddress() + + // 这里只是示例,实际需要处理路由添加、更新、超时等逻辑 + System.out.println("Received route: " + entry.getIpAddress().getHostAddress() + " via " + entry.getNextHop().getHostAddress() + " metric: " + entry.getMetric()); } diff --git a/src/main/java/cn/x47/model/RIPEntry.java b/src/main/java/cn/x47/model/RIPEntry.java index 2636d41..087bdd7 100644 --- a/src/main/java/cn/x47/model/RIPEntry.java +++ b/src/main/java/cn/x47/model/RIPEntry.java @@ -11,7 +11,7 @@ public class RIPEntry { private InetAddress ipAddress; private InetAddress subnetMask; // RIP v2 特有 private InetAddress nextHop; // RIP v2 特有 - private long metric; + private int metric; } diff --git a/src/main/java/cn/x47/service/RIPClient.java b/src/main/java/cn/x47/service/RIPClient.java index 69c4f5d..569cac3 100644 --- a/src/main/java/cn/x47/service/RIPClient.java +++ b/src/main/java/cn/x47/service/RIPClient.java @@ -4,13 +4,12 @@ package cn.x47.service; import cn.x47.handle.RIPPacketEncoder; import cn.x47.model.RIPPacket; import io.netty.bootstrap.Bootstrap; -import io.netty.channel.*; -import io.netty.channel.socket.nio.NioDatagramChannel; -import io.netty.channel.socket.DatagramChannel; - +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; import io.netty.channel.nio.NioEventLoopGroup; - - +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.nio.NioDatagramChannel; public class RIPClient { @@ -33,14 +32,21 @@ public class RIPClient { public void sendRipPacket(RIPPacket packet) { try { - ChannelFuture future = bootstrap.bind(0).sync(); - future.channel().writeAndFlush(packet).sync(); - future.channel().close(); + ChannelFuture future = bootstrap.bind(600).sync(); // 部分环境下需不同端口尝试 + future.channel().writeAndFlush(packet).addListener(f -> { + if (f.isSuccess()) { + System.out.println("Packet sent successfully"); + } else { + System.err.println("Failed to send packet: " + f.cause().getMessage()); + } + }); + future.channel().closeFuture().sync(); // 等待,保持通道开启 } catch (InterruptedException e) { e.printStackTrace(); } } + public void shutdown() { group.shutdownGracefully(); } diff --git a/src/main/java/cn/x47/service/RoutingTable.java b/src/main/java/cn/x47/service/RoutingTable.java deleted file mode 100644 index 96e1606..0000000 --- a/src/main/java/cn/x47/service/RoutingTable.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.x47.service; - - -import cn.x47.model.RIPEntry; - -import java.net.InetAddress; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class RoutingTable { - private static RoutingTable instance = new RoutingTable(); - private Map routes; - - private RoutingTable() { - routes = new ConcurrentHashMap<>(); - } - - public static RoutingTable getInstance() { - return instance; - } - - public void updateRoute(RIPEntry entry) { - // 简单地将新路由添加或更新到路由表中 - routes.put(entry.getIpAddress(), entry); - } - - public void removeRoute(InetAddress ipAddress) { - routes.remove(ipAddress); - } - - public Map getRoutes() { - return routes; - } - - public RIPEntry getRoute(InetAddress ipAddress) { - return routes.get(ipAddress); - } -}