
前段时间在配置ipv6时候,遇到了ND和PD配置的问题,搞了半天才搞懂他们俩到底是啥关系,然后在配置的时候又经常把两个地址配错,配反了!
这里普及下ND和PD的关系:“ND互联地址 ”是给交换机和路由器用的,而“PD业务地址”
就是给服务器和手机电脑等等的客户端用的,总结下来按我的理解ND就是桥梁,pd就是客户端!
后面我觉得手动配置实在是太麻烦,于是乎就叫ai写了个脚本,由于我的交换机是H3CS5800,这个版本的代码可以在这个交换机下面直接粘贴使用,代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>交换机调试命令生成工具(纯IPv6版)</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#165DFF',
secondary: '#36CFC9',
dark: '#1D2129',
light: '#F2F3F5'
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
}
}
}
</script>
<style type="text/tailwindcss">
@layer utilities {
.input-focus {
@apply focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none;
}
.card-shadow {
@apply shadow-lg shadow-primary/10 hover:shadow-xl hover:shadow-primary/20 transition-all;
}
.btn-effect {
@apply hover:scale-105 active:scale-95 transition-transform;
}
.tab-active {
@apply border-b-2 border-primary text-primary font-medium;
}
}
</style>
</head>
<body class="bg-gray-50 min-h-screen py-8 px-4">
<div class="max-w-5xl mx-auto">
<!-- 页面标题 -->
<div class="text-center mb-6">
<h1 class="text-[clamp(1.8rem,4vw,2.8rem)] font-bold text-dark mb-2">交换机调试命令生成工具</h1>
<p class="text-gray-500 text-lg">精准解析IPv6关键信息/手动输入,一键生成H3C纯IPv6配置命令</p>
</div>
<!-- 输入模式标签 -->
<div class="flex border-b border-gray-200 mb-4 max-w-4xl mx-auto">
<button id="parse-tab" class="tab-active py-2 px-6 text-lg">智能解析模式</button>
<button id="manual-tab" class="py-2 px-6 text-lg text-gray-500">手动输入模式</button>
</div>
<!-- 智能解析模式面板 -->
<div id="parse-panel" class="bg-white rounded-xl p-6 mb-6 card-shadow max-w-4xl mx-auto block">
<label class="block text-sm font-medium text-gray-700 mb-2">
粘贴业务数据(自动提取VLAN/PD/ND地址)<span class="text-red-500">*</span>
</label>
<!-- 清空默认value,仅保留placeholder提示 -->
<textarea id="parse-text" class="w-full h-48 px-4 py-2 border border-gray-300 rounded-lg input-focus font-mono text-sm" placeholder="粘贴示例:
(无关文本可随意包含,工具仅提取VLAN/PD/ND)
公司名称/业务编号等冗余内容
VLAN:873
IPv6:
PD业务地址:2409:876c:5411:c0::/64
ND互联地址:2409:876c:5401:100c::/64
掩码64"></textarea>
<!-- 解析辅助配置 -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-6">
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">进口口号 <span class="text-red-500">*</span></label>
<input type="number" id="parse-in-port" class="w-full px-4 py-2 border border-gray-300 rounded-lg input-focus" placeholder="例:48" min="1" max="100">
</div>
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">出口口号 <span class="text-red-500">*</span></label>
<input type="number" id="parse-out-port" class="w-full px-4 py-2 border border-gray-300 rounded-lg input-focus" placeholder="例:49" min="1" max="100">
</div>
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">出口接口类型</label>
<select id="parse-out-type" class="w-full px-4 py-2 border border-gray-300 rounded-lg input-focus bg-white">
<option value="">请选择接口类型</option>
<option value="ten">万兆(Ten-GigabitEthernet)</option>
<option value="giga">千兆(GigabitEthernet)</option>
</select>
</div>
</div>
</div>
<!-- 手动输入模式面板(纯IPv6,无IPv4项) -->
<div id="manual-panel" class="bg-white rounded-xl p-6 mb-6 card-shadow max-w-4xl mx-auto hidden">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- VLAN号 -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700" for="manual-vlan">
VLAN号 <span class="text-red-500">*</span>
</label>
<input type="number" id="manual-vlan" class="w-full px-4 py-2 border border-gray-300 rounded-lg input-focus" placeholder="例:873" min="1" max="4094">
</div>
<!-- PD业务地址 -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700" for="manual-pd-addr">
PD业务地址 <span class="text-red-500">*</span>
</label>
<input type="text" id="manual-pd-addr" class="w-full px-4 py-2 border border-gray-300 rounded-lg input-focus" placeholder="例:2409:876c:5411:c0::/64">
</div>
<!-- ND互联地址 -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700" for="manual-nd-addr">
ND互联地址 <span class="text-red-500">*</span>
</label>
<input type="text" id="manual-nd-addr" class="w-full px-4 py-2 border border-gray-300 rounded-lg input-focus" placeholder="例:2409:876c:5401:100c::/64">
</div>
<!-- 进口口号 -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700" for="manual-in-port">
进口口号 <span class="text-red-500">*</span>
</label>
<input type="number" id="manual-in-port" class="w-full px-4 py-2 border border-gray-300 rounded-lg input-focus" placeholder="例:48" min="1" max="100">
</div>
<!-- 出口口号 -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700" for="manual-out-port">
出口口号 <span class="text-red-500">*</span>
</label>
<input type="number" id="manual-out-port" class="w-full px-4 py-2 border border-gray-300 rounded-lg input-focus" placeholder="例:49" min="1" max="100">
</div>
<!-- 出口接口类型 -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700" for="manual-out-type">
出口接口类型
</label>
<select id="manual-out-type" class="w-full px-4 py-2 border border-gray-300 rounded-lg input-focus bg-white">
<option value="">请选择接口类型</option>
<option value="ten">万兆(Ten-GigabitEthernet)</option>
<option value="giga">千兆(GigabitEthernet)</option>
</select>
</div>
</div>
</div>
<!-- 生成按钮 -->
<div class="text-center mb-6 max-w-4xl mx-auto">
<button id="generate-btn" class="px-10 py-3 bg-primary text-white font-medium rounded-lg shadow-md btn-effect flex items-center justify-center mx-auto">
<i class="fa fa-magic mr-2"></i> 一键生成IPv6配置命令
</button>
</div>
<!-- 命令输出区域 -->
<div class="bg-white rounded-xl p-6 card-shadow max-w-4xl mx-auto hidden" id="output-area">
<div class="flex flex-wrap justify-between items-center mb-4">
<h3 class="text-lg font-semibold text-dark flex items-center">
<i class="fa fa-code mr-2 text-primary"></i> 生成的H3C纯IPv6交换机配置命令
</h3>
<div class="flex gap-2">
<button id="copy-btn" class="px-4 py-1.5 bg-secondary text-white rounded-lg text-sm btn-effect flex items-center">
<i class="fa fa-copy mr-1"></i> 复制到剪贴板
</button>
<button id="reset-btn" class="px-4 py-1.5 bg-gray-200 text-gray-700 rounded-lg text-sm btn-effect flex items-center">
<i class="fa fa-refresh mr-1"></i> 重置
</button>
</div>
</div>
<pre class="bg-gray-50 p-4 rounded-lg border border-gray-200 overflow-x-auto text-sm font-mono" id="command-output"></pre>
</div>
</div>
<script>
// DOM元素获取
const parseTab = document.getElementById('parse-tab');
const manualTab = document.getElementById('manual-tab');
const parsePanel = document.getElementById('parse-panel');
const manualPanel = document.getElementById('manual-panel');
const generateBtn = document.getElementById('generate-btn');
const copyBtn = document.getElementById('copy-btn');
const resetBtn = document.getElementById('reset-btn');
const outputArea = document.getElementById('output-area');
const commandOutput = document.getElementById('command-output');
// 解析模式元素
const parseText = document.getElementById('parse-text');
const parseInPort = document.getElementById('parse-in-port');
const parseOutPort = document.getElementById('parse-out-port');
const parseOutType = document.getElementById('parse-out-type');
// 手动模式元素
const manualVlan = document.getElementById('manual-vlan');
const manualPdAddr = document.getElementById('manual-pd-addr');
const manualNdAddr = document.getElementById('manual-nd-addr');
const manualInPort = document.getElementById('manual-in-port');
const manualOutPort = document.getElementById('manual-out-port');
const manualOutType = document.getElementById('manual-out-type');
// 模式切换
parseTab.addEventListener('click', () => {
parseTab.classList.add('tab-active');
manualTab.classList.remove('tab-active');
manualTab.classList.add('text-gray-500');
parsePanel.style.display = 'block';
manualPanel.style.display = 'none';
});
manualTab.addEventListener('click', () => {
manualTab.classList.add('tab-active');
parseTab.classList.remove('tab-active');
parseTab.classList.add('text-gray-500');
manualPanel.style.display = 'grid';
parsePanel.style.display = 'none';
});
// 核心:精准解析(仅提取VLAN/PD业务地址/ND互联地址,忽略IPv4和所有无关内容)
function parseBusinessText(text) {
const result = {
vlan: '',
pdAddr: '',
ndAddr: ''
};
// 1. 提取VLAN号(匹配 VLAN:xxx / VLAN:xxx / VLAN xxx 格式)
const vlanReg = /VLAN[::\s]*(\d{1,4})/i;
const vlanMatch = text.match(vlanReg);
if (vlanMatch) result.vlan = vlanMatch[1];
// 2. 提取PD业务地址(仅匹配 PD业务地址:xxx / PD业务地址:xxx 格式)
const pdReg = /PD业务地址[::\s]*([0-9a-fA-F:]+\/\d{1,3})/i;
const pdMatch = text.match(pdReg);
if (pdMatch) result.pdAddr = pdMatch[1];
// 3. 提取ND互联地址(仅匹配 ND互联地址:xxx / ND互联地址:xxx 格式)
const ndReg = /ND互联地址[::\s]*([0-9a-fA-F:]+\/\d{1,3})/i;
const ndMatch = text.match(ndReg);
if (ndMatch) result.ndAddr = ndMatch[1];
return result;
}
// 生成纯IPv6配置命令主函数(增加接口类型校验)
generateBtn.addEventListener('click', function() {
let data = {
vlan: '',
pdAddr: '',
ndAddr: '',
inPort: '',
outPort: '',
outType: ''
};
// 根据当前模式获取数据
if (parsePanel.style.display === 'block') {
// 智能解析模式:仅提取VLAN/PD/ND
const parseRes = parseBusinessText(parseText.value);
data.vlan = parseRes.vlan;
data.pdAddr = parseRes.pdAddr;
data.ndAddr = parseRes.ndAddr;
data.inPort = parseInPort.value.trim();
data.outPort = parseOutPort.value.trim();
data.outType = parseOutType.value.trim();
} else {
// 手动输入模式:纯IPv6相关参数
data.vlan = manualVlan.value.trim();
data.pdAddr = manualPdAddr.value.trim();
data.ndAddr = manualNdAddr.value.trim();
data.inPort = manualInPort.value.trim();
data.outPort = manualOutPort.value.trim();
data.outType = manualOutType.value.trim();
}
// 基础校验(必选参数,新增接口类型校验)
const required = [data.vlan, data.pdAddr, data.ndAddr, data.inPort, data.outPort, data.outType];
if (required.some(item => !item)) {
alert('请确保VLAN号、PD业务地址、ND互联地址、进/出口口号、出口接口类型均已解析/填写!');
return;
}
// IPv6 CIDR格式校验
const ipv6CidrRegex = /^([0-9a-fA-F:]+)\/\d{1,3}$/;
if (!ipv6CidrRegex.test(data.pdAddr) || !ipv6CidrRegex.test(data.ndAddr)) {
alert('PD/ND地址格式错误!请填写如 2409:876c:5411:c0::/64 的IPv6 CIDR格式');
return;
}
// 提取地址前缀和掩码,构造IPv6配置地址
const pdPrefix = data.pdAddr.split('/')[0];
const ndPrefix = data.ndAddr.split('/')[0];
const ipv6Cidr = data.pdAddr.split('/')[1];
const pdIpv6 = `${pdPrefix}1/${ipv6Cidr}`.toUpperCase(); // PD+::1/64
const ndIpv6 = `${ndPrefix}2/${ipv6Cidr}`.toUpperCase(); // ND+::2/64
const ipv6Route = `${ndPrefix}1`.toUpperCase(); // 路由下一跳ND+::1
// 接口类型定义
const inInterface = 'GigabitEthernet'; // 进口固定千兆
const outInterface = data.outType === 'ten' ? 'Ten-GigabitEthernet' : 'GigabitEthernet';
// 拼接纯IPv6配置命令(严格按要求格式,无任何IPv4相关内容)
const commands = `vlan ${data.vlan}
quit
interface Vlan-interface ${data.vlan}
ipv6 address ${ndIpv6}
ipv6 address ${pdIpv6}
quit
interface ${inInterface} 1/0/${data.inPort}
port access vlan ${data.vlan}
quit
interface ${outInterface} 1/0/${data.outPort}
port access vlan ${data.vlan}
quit
ipv6 route-static :: 0 ${ipv6Route}
sa`;
// 显示输出并滚动到视图
outputArea.classList.remove('hidden');
commandOutput.textContent = commands;
outputArea.scrollIntoView({ behavior: 'smooth' });
});
// 复制到剪贴板功能(带成功提示)
copyBtn.addEventListener('click', function() {
const text = commandOutput.textContent;
navigator.clipboard.writeText(text).then(() => {
const original = copyBtn.innerHTML;
copyBtn.innerHTML = '<i class="fa fa-check mr-1"></i> 复制成功';
copyBtn.classList.remove('bg-secondary');
copyBtn.classList.add('bg-green-500');
setTimeout(() => {
copyBtn.innerHTML = original;
copyBtn.classList.remove('bg-green-500');
copyBtn.classList.add('bg-secondary');
}, 3000);
}).catch(err => {
alert('复制失败,请手动复制!');
console.error('复制错误:', err);
});
});
// 重置功能:清空所有输入,恢复默认空状态
resetBtn.addEventListener('click', function() {
parseText.value = '';
// 重置手动输入框为清空状态(无默认值)
manualVlan.value = '';
manualPdAddr.value = '';
manualNdAddr.value = '';
manualInPort.value = '';
manualOutPort.value = '';
manualOutType.value = '';
// 重置解析模式输入框
parseInPort.value = '';
parseOutPort.value = '';
parseOutType.value = '';
// 清空输出并隐藏
commandOutput.textContent = '';
outputArea.classList.add('hidden');
// 切回解析模式
parseTab.click();
});
// 回车触发生成(输入框/下拉框,排除文本域)
document.querySelectorAll('input, select').forEach(el => {
el.addEventListener('keydown', e => {
if (e.key === 'Enter') {
e.preventDefault();
generateBtn.click();
}
});
});
</script>
</body>
</html>
我把代码写在这个网页上面了,在下面直接输入PD和ND,还有vlan信息,接口信息就行了,直接复制粘贴到交换机一键执行!
交换机调试命令生成工具
精准解析IPv6关键信息/手动输入,一键生成H3C纯IPv6配置命令
