GGP 协议详解
GGP(Gateway-to-Gateway Protocol,网关到网关协议)是ARPANET早期使用的路由协议之一,定义在 RFC 823(1982年),用于核心网关(Core Gateways)之间的路由信息交换。它是现代链路状态路由协议(如OSPF)的先驱,但因设计缺陷和网络演进已被完全淘汰。
1. GGP 协议概述
基本概念
- 作用:核心网关间交换网络可达性信息,构建全网路由表
- 发布年份:1982年(RFC 823)
- 协议类型:距离矢量 + 链路状态混合
- 传输协议:IP协议号3(GGP)
- 状态:已废弃,被EGP(RFC 904)取代
- 工作范围:ARPANET核心骨干网
GGP vs 现代协议
特性 | GGP | EGP | BGP/OSPF |
---|
路由类型 | 混合(DV+LS) | 外部网关 | BGP=路径向量,OSPF=链路状态 |
收敛速度 | 慢 | 中等 | 快 |
扩展性 | 差 | 中等 | 优秀 |
稳定性 | 差(计数到无穷) | 中等 | 高 |
认证 | 无 | 无 | 支持 |
状态 | 已废弃 | 已废弃 | 当前使用 |
历史背景
- ARPANET时期:核心网关负责骨干路由
- 设计目标:简单可靠的路由更新
- 局限性:不支持AS概念,难以扩展
2. GGP 协议机制
核心组件
- Hello消息:邻居发现和链路状态检测
- IH(Initial Hello):初始化连接
- DD(Direct Dump):直接转储路由表
- IDU(Indirect Dump):间接路由信息
- CE(Completion Echo):同步完成确认
路由计算
- 链路状态信息:通过Hello收集直接邻居状态
- 距离矢量更新:周期性交换完整路由表
- Bellman-Ford算法:计算最短路径
消息交互流程
1. 网关启动 → 发送IH到邻居
2. 邻居响应Hello → 建立邻接关系
3. 周期性DD/IDU → 交换路由信息
4. 计算路由表 → 更新转发表
5. CE确认 → 同步完成
3. GGP 报文格式
基本头部(8字节)
+----------+----------+----------+----------+
| Version | Type | Checksum | Sequence |
+----------+----------+----------+----------+
| 源网关ID (4字节) |
+--------------------------------------------------------+
| 数据部分 (可变) |
+--------------------------------------------------------+
字段说明
字段 | 大小 | 说明 |
---|
Version | 1字节 | 协议版本(1=GGP) |
Type | 1字节 | 消息类型 |
Checksum | 2字节 | 整个GGP数据报校验和 |
Sequence | 2字节 | 消息序列号,防重放 |
Source ID | 4字节 | 发送网关唯一标识 |
消息类型
类型 | 值 | 说明 |
---|
Hello | 0 | 邻居发现和保持 |
IH | 1 | 初始Hello |
DD | 2 | 直接转储(完整路由表) |
IDU | 3 | 间接转储(部分更新) |
CE | 4 | 完成回显 |
Hello消息格式
+----------+----------+----------+----------+
| Ver=1 | Type=0 | Checksum | Seq |
+----------+----------+----------+----------+
| Source ID| 状态标志 (Metrics, State) |
+----------+-------------------------------------------------+
| 邻居列表 (每个4字节:ID + 指标) |
+--------------------------------------------------------+
DD/IDU消息格式
GGP头部 + 网络描述符列表
每个网络描述符:
- 网络号 (24位)
- 跳数 (8位)
- 标志 (可用性等)
4. GGP 工作流程
邻接建立
网关A → IH → 网关B
网关B → Hello → 网关A (确认邻接)
网关A → DD → 网关B (完整路由表)
网关B → 计算路由 → 更新转发表
路由更新周期
1. 每30秒:发送Hello保持邻接
2. 每120秒:发送DD完整转储
3. 变化时:发送IDU增量更新
4. 接收方:合并信息,重新计算
5. 超时:邻居失效,触发重计算
路由表结构
网络号 → {下一跳, 指标, 序列号, 最后更新时间}
指标:链路成本(通常跳数)
序列号:版本控制,检测陈旧信息
5. GGP 的技术特性
混合路由算法
链路状态部分:
- Hello收集直接邻居LSA(Link State Advertisement)
- 构建网络拓扑图
距离矢量部分:
- DD/IDU交换完整/增量路由表
- Bellman-Ford松弛算法
问题:信息不一致导致路由环和慢收敛
序列号机制
- 递增序列号:每个路由更新携带版本
- 陈旧检测:接收方丢弃低序列号信息
- 环预防:部分解决计数到无穷问题
指标计算
- 默认指标:1跳 = 1单位
- 动态调整:基于链路质量
- 无穷大:16(类似RIP)
6. GGP 的局限性和问题
主要缺陷
- 慢收敛:距离矢量特性,环路恢复慢
- 路由环:毒性逆转(Poison Reverse)不完整
- 扩展性差:全网广播,O(n²)消息复杂度
- 无分层:不支持AS间路由
- 无认证:易受路由欺骗
- 信息洪泛:核心网关负载高
计数到无穷问题
A→B→C,C故障
B仍通告C可达(旧信息)
A→B→C环路形成
B检测超时后,指标逐渐增加到无穷
收敛时间 = 故障传播时间 × 网络直径
被EGP取代的原因
- EGP引入AS概念:分层路由
- 更好的稳定性:可靠传输,ACK机制
- 外部网关定位:明确边界路由角色
- 向BGP演进:路径属性,策略路由
7. GGP 实现和配置(历史)
早期BSD实现
// 简化GGP伪代码
struct ggp_header {
uint8_t version;
uint8_t type;
uint16_t checksum;
uint16_t sequence;
uint32_t source_id;
};
void send_ggp_hello(struct neighbor *nb) {
struct ggp_header hdr = {
.version = 1,
.type = 0, // Hello
.sequence = next_sequence++
};
hdr.checksum = ggp_checksum(&hdr);
send_ip_packet(IPPROTO_GGP, &hdr, sizeof(hdr), nb->ip);
}
void process_dd(struct ggp_header *hdr, uint8_t *routes) {
merge_routes(hdr->source_id, routes);
recompute_routing_table();
send_ce_ack(hdr->sequence);
}
配置示例(历史系统)
# 早期网关配置(类似)
route add -net 10.0.0.0 gw 192.168.1.1 metric 1 proto ggp
gated.conf: # 早期路由守护进程
protocol GGP {
enable;
preference 10;
interface all {
enable;
hellos 30;
dumps 120;
}
};
8. GGP 与现代协议的对比
演进路径
GGP (1982) → EGP (1984) → BGP (1989) → BGP-4 (1994)
↓ ↓ ↓ ↓
混合路由 外部网关 路径向量 策略路由
全网洪泛 AS分层 AS_PATH CIDR支持
无认证 可靠传输 MD5认证 路由反射
已废弃 已废弃 当前AS间 当前标准
技术对比
特性 | GGP | OSPF | BGP |
---|
算法 | DV+LS混合 | 链路状态 | 路径向量 |
范围 | 核心网 | AS内 | AS间 |
收敛 | 慢 | 快 | 中等 |
扩展性 | 差 | 好 | 优秀 |
消息复杂度 | O(n²) | O(n log n) | 按需 |
9. GGP 的历史意义
贡献和遗产
- 链路状态先驱:Hello机制影响OSPF/IS-IS
- 序列号控制:版本检测思想延续
- 网关概念:早期路由器设计基础
- 混合算法尝试:路由协议演进启发
协议演进树
早期内部网关协议
├── GGP (RFC 823) → 已废弃
├── HELLO (RFC 891) → 已废弃
└── RIP (RFC 1058) → 仍有限使用
↓
外部网关协议
└── EGP (RFC 904) → BGP (RFC 1105/1163/1654/4271)
内部网关协议现代
├── OSPF (RFC 2328)
└── IS-IS (ISO 10589)
10. 抓包分析和模拟
Wireshark分析(历史流量)
# GGP协议过滤
ip.proto == 3 # GGP协议号
ggp # 如果有GGP解码器
# 消息类型分析
frame[20:1] == 0x00 and ip.proto == 3 # Hello
模拟GGP环境
# Scapy模拟GGP(仅教育用途)
from scapy.all import *
class GGP(Packet):
name = "GGP"
fields_desc = [
ByteField("version", 1),
ByteField("type", 0),
ShortField("checksum", 0),
ShortField("sequence", 0),
IntField("source_id", 0)
]
def post_build(self, p, pay):
if self.checksum == 0:
ck = checksum(p + pay)
p = p[:4] + struct.pack("!H", ck) + p[6:]
return p + pay
# 发送Hello
ggp_hello = IP(proto=3)/GGP(type=0, sequence=1, source_id=12345)
send(ggp_hello)
11. 迁移和兼容性
从GGP到EGP迁移
# 历史迁移步骤
1. 双协议运行:GGP + EGP并存
2. AS边界配置:核心网→AS核心
3. 逐步替换:外围网关先迁移
4. 关闭GGP:确认EGP稳定后
遗留系统支持
- 现代系统:无GGP支持
- 历史工具:gated(支持GGP/EGP/RIP)
- 模拟器:ns-3、OMNeT++可模拟
12. 安全问题(历史视角)
历史攻击向量
- 路由欺骗:伪造DD/IDU消息
- 序列号预测:重放旧路由信息
- 邻接劫持:伪造Hello建立假邻接
- DoS攻击:洪泛路由更新
防护缺失
- 无认证:明文传输,易篡改
- 无加密:路由信息公开
- 无速率限制:易受洪泛攻击
13. 故障排除(历史参考)
常见历史问题
问题 | 原因 | 解决(当时) |
---|
邻接不建立 | Hello超时 | 检查链路,调整定时器 |
路由环 | 信息不同步 | 强制DD重同步 |
慢收敛 | 大网络直径 | 分区网络,增加核心网关 |
序列冲突 | 重启后序列丢失 | 手动重置序列号 |
诊断方法
# 历史诊断(gated日志)
tail -f /var/log/gated.log | grep GGP
# 检查邻接:show ggp neighbors
# 路由表:show route protocol ggp
14. 现代视角和研究价值
学术意义
- 路由协议演化:理解从DV到LS的过渡
- 历史教训:扩展性、稳定性的重要性
- 协议设计:混合算法的得失
模拟和研究
# ns-3 GGP模拟(概念)
class GGPHelper:
def Install(self, nodes):
for node in nodes:
node.AddProtocolHandler(ggp_tx,
Ipv4L3Protocol.GetTypeId(), 3)
def EnableLogging(self):
LogComponentEnable("GGP", LOG_LEVEL_ALL)
遗留网络支持
- 博物馆网络:历史ARPANET重建
- 协议分析:网络考古研究
- 教育用途:路由协议教学
GGP协议作为ARPANET时代的核心路由解决方案,虽然技术上已被淘汰,但其设计思想对现代路由协议的发展产生了深远影响。研究GGP有助于理解互联网路由架构的演进历程,以及协议设计中稳定性和扩展性的权衡考量。在现代网络中,BGP和OSPF/IS-IS已完全取代了GGP的功能,但其历史地位不可忽视。