- 论坛徽章:
- 0
|
最近做一个ipv6下组播的东西,顺便学习v4组播,在这里奉献给那些需要的人。希望我的努力能给你工作带来方便。
对linux下ipv6路由或组播有兴趣可以一起研究一下,联系方式redog@sina.com
该文档介绍了linux多播路由的配置过程,并给出了相关的测试程序。
一 测试环境
1 网络拓扑
交换机
internet route
eth1 eth0
(不好意思网络拓扑帖不上)
ip地址分配:(linux图形下进行配置)
eth1:202.198.a.b //外网入口
eth0:192.168.0.1 //内网出口
host1:192.168.0.2 //子网内主机
host2:192.168.0.3 //子网内主机
2 对外访问
这里我们采用的是简单的NAT(可参考局域网建设相关内容),使得内网可以访问外网
在/etc/rc.local中加入以下内容
echo "1">;/proc/sys/net/ipv4/ip_forward //开启转发功能
/sbin/modprobe ip_tables //加载相应的内核过滤模块
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_nat
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_nat_ftp
iptables -A POSTROUTING -t nat -s 192.168.0.0/24 -o eth1 -j SNAT --to-source 202.198.a.b
保存文件
chmod +x /etc/rc.local
执行文件/etc/rc.local
测试局域网:
host1上:ping 192.168.0.2
ping 192.168.0.1
ping 202.198..a.254 //route的网关地址 这一步通了说明我们已经配置成功了
我们的网络可以很好的工作了,但是还不知组播,接下来我们让它来为我们的组播工作。
二 配置多播路由
1. 软件需求:
mrouted3.9beta3
ftp://ftp.rge.com//pub/communications/ipmulti/beta-test/mrouted-3.9-beta3.tar.gz
mrouted Linux patch:
ftp://ftp.debian.org/debian/dists/potato/non-free/source/net/mrouted_3.9-beta3-1.diff.gz
2 内核要求:
linux内核(我的rh9 2.4.20) 改内核不需要重新编译已经满足一下条件
以下几项需要选中
Networking options --->;
IP: multicasting IP: advanced routerIP: multicast routing
IP: PIM-SM version 1 support
IP: PIM-SM version 2 support
3 安装mrouted:
假设你的文件下载到/tmp目录
cd /usr/src
tar xvzf /tmp/mrouted-3.9-beta3.tar.gz
gunzip /tmp/mrouted_3.9-beta3-1.diff.gz | patch -p0
得到的输出结果
patching file `mrouted-3.9-beta3.orig/Makefile'
patching file `mrouted-3.9-beta3.orig/defs.h'
patching file `mrouted-3.9-beta3.orig/pathnames.h'
patching file `mrouted-3.9-beta3.orig/debian/init.d'
patching file `mrouted-3.9-beta3.orig/debian/changelog'
patching file `mrouted-3.9-beta3.orig/debian/copyright'
patching file `mrouted-3.9-beta3.orig/debian/dirs'
patching file `mrouted-3.9-beta3.orig/debian/control'
patching file `mrouted-3.9-beta3.orig/debian/rules'
patching file `mrouted-3.9-beta3.orig/debian/README.debian'
patching file `mrouted-3.9-beta3.orig/igmp.i'
patching file `mrouted-3.9-beta3.orig/netinet/ip_mroute.h'
patching file `mrouted-3.9-beta3.orig/vers.c'
cd mrouted*
该软件是应用在FreeBSD下,要再我们这里使用需要做一下修改
998: fprintf(stderr, "%02d:%02d:%02d.%03ld %s", thyme->;tm_hour,
999: thyme->;tm_min, thyme->;tm_sec, now.tv_usec / 1000, msg);
修改成:
998: fprintf(stderr, "now: %s",
999: msg);
make
到这里mrouted安装完毕。
4 mroute配置文件
安装完之后,我们创建文件/etc/mrouted.conf,加入以下内容,我们也可以使用默认配置。
phyint eth0 rate_limit 0 igmpv1
phyint eth1 rate_limit 0 igmpv1
在这里你可以加更多的配置信息,上面两句是说明mrouted使用igmpv1在eth0和eth1接口,并且rate limit为0, 现在的linux都支持igmpv1和igmpv2但是我们测试v2是否在这里也能工作。
5 配置静态路由:
route add –net 224.0.0.0 netmask 240.0.0.0 dev eth0
这里的eth0是组播数据的出口,你可以根据自己的情况修改。
启动mrouted
mrouted –c /etc/mrouted.conf –d
可以把它的启动加在/etc/rc.local中。
三 测试
服务器端程序
#include<>;
int port=5000;
int main(void)
{
int socket_descriptor;
struct sockaddr_in address;
/* 首先建立套接口 */
socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_descriptor == -1)
{
perror("Opening socket" ;
exit(EXIT_FAILURE);
}
/* 初始化IP多播地址 */
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("224.1.2.3" ;
address.sin_port = htons(port);
/* 开始进行IP多播 */
while(1) {
if(sendto(socket_descriptor, "test from broadcast",sizeof("test from broadcast" , 0, (struct sockaddr *)&address, sizeof(address)) < 0)
{
perror("sendto" ;
exit(EXIT_FAILURE);
}
sleep(2);
}
exit(EXIT_SUCCESS);
}
客户端程序
#include < >;
/* 多播IP地址 */
int port = 5000;
int main(void)
{
struct ip_mreq command;
int loop = 1;
/* 多播循环 */
int iter = 0;
int sin_len;
char message[256];
int socket_descriptor;
struct sockaddr_in sin;
struct hostent *server_host_name;
if((server_host_name = gethostbyname(host_name)) == 0)
{
perror("gethostbyname" ;
exit(EXIT_FAILURE);
}
/*bzero(&sin, sizeof(sin));*/
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(port);
if((socket_descriptor = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
{ perror("socket" ;
exit(EXIT_FAILURE);
}
/* 调用bind之前,设置套接口选项启用多播IP支持*/
loop = 1;
if(setsockopt(socket_descriptor,SOL_SOCKET, SO_REUSEADDR,&loop, sizeof(loop)) < 0){
perror("setsockopt:SO_REUSEADDR" ;
exit(EXIT_FAILURE);
}
if(bind(socket_descriptor,(struct sockaddr *)&sin, sizeof(sin)) < 0)
{
perror("bind" ;
exit(EXIT_FAILURE);
}
/* 在同一个主机上进行广播设置套接口,作用是方便单个开发系统上测试多播IP广播 */
loop = 1;
if(setsockopt(socket_descriptor,IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0)
{
perror("setsockopt:IP_MULTICAST_LOOP" ;
exit(EXIT_FAILURE);
}
/* 加入一个广播组。进一步告诉Linux内核,*/
command.imr_multiaddr.s_addr = inet_addr("224.1.2.3" ;
command.imr_interface.s_addr = htonl(INADDR_ANY);
if(command.imr_multiaddr.s_addr == -1)
{
perror("224.1.2.3 not a legal multicast address");
exit(EXIT_FAILURE);
}
if (setsockopt(socket_descriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command, sizeof(command)) < 0){
perror("setsockopt:IP_ADD_MEMBERSHIP");
}
while(iter++ < 
{
sin_len = sizeof(sin);
if(recvfrom(socket_descriptor, message, 256, 0,(struct sockaddr *)&sin, &sin_len) == -1) {
perror("recvfrom");
}
printf("Response #%-2d from server: %s\n", iter, message);
sleep(2); }
/* 接受8个广播后退出 */
if(setsockopt(socket_descriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP, &command, sizeof(command)) < 0) {
perror("setsockopt:IP_DROP_MEMBERSHIP");
}
close(socket_descriptor);
exit(EXIT_SUCCESS);
}
我们这里使用的都是linux系统,编译上面两个程序,我们在202.198.a.c(和202.198.a.b在同一个子网内)于行服务器,在host1和host2上面运行客户端程序就可以看到我们同时收到了来自202.198.a.c发来的组播报文
到这里我的工作就结束了,当然了你可以在这上面做很多的东西。 |
|