Sockets 使用辅助IP地址连接套接字
不久前,我能够通过以下步骤从给定接口上的主IP地址或辅助IP地址连接到给定的目标地址Sockets 使用辅助IP地址连接套接字,sockets,tcp,routing,linux-kernel,ip,Sockets,Tcp,Routing,Linux Kernel,Ip,不久前,我能够通过以下步骤从给定接口上的主IP地址或辅助IP地址连接到给定的目标地址 使用IP addr add…向给定接口添加辅助IP地址 根据需要将套接字绑定到主地址或辅助地址 使用#2中绑定的主地址或辅助地址连接到目标ip地址 我最近将一台机器升级到了Linux3.3.6,但这台机器已经不能工作了,但我不记得我上一次尝试的版本是什么了。有人知道如何在更新的内核中做同样的事情吗?我刚刚在另一台机器上验证了2.6.23上的相同代码 更新2这似乎与NIC驱动程序有关。有了3.3.6和8139,一
IP addr add…
向给定接口添加辅助IP地址tshark
后台运行的数据包捕获输出)上运行代码(末尾的源代码)时发生的情况:
然后在第2.6.23节中进行同样的操作:
$ ./bind_connect 10.0.0.123 10.0.0.226 >
Bound socket: 10.0.0.226 [10.0.0.226->10.0.0.123]
$ 231.566278 10.0.0.226 -> 10.0.0.123 TCP 54109 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=99922052 TSER=0 WS=5
231.566448 10.0.0.123 -> 10.0.0.226 TCP http > 54109 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=7060755 TSER=99922052 WS=1
231.566463 10.0.0.226 -> 10.0.0.123 TCP 54109 > http [ACK] Seq=1 Ack=1 Win=5856 Len=0 TSV=99922052 TSER=7060755
231.566510 10.0.0.226 -> 10.0.0.123 TCP 54109 > http [FIN, ACK] Seq=1 Ack=1 Win=5856 Len=0 TSV=99922052 TSER=7060755
231.566593 10.0.0.123 -> 10.0.0.226 TCP http > 54109 [ACK] Seq=1 Ack=2 Win=5792 Len=0 TSV=7060755 TSER=99922052
231.566704 10.0.0.123 -> 10.0.0.226 TCP http > 54109 [FIN, ACK] Seq=1 Ack=2 Win=5792 Len=0 TSV=7060755 TSER=99922052
231.566737 10.0.0.226 -> 10.0.0.123 TCP 54109 > http [ACK] Seq=2 Ack=2 Win=5856 Len=0 TSV=99922052 TSER=7060755
$ ./bind_connect 10.0.0.123 10.0.0.126 >
Bound socket: 10.0.0.126 [10.0.0.126->10.0.0.123]
$ 235.824867 10.0.0.126 -> 10.0.0.123 TCP 34228 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=99926310 TSER=0 WS=5
235.825185 10.0.0.123 -> 10.0.0.126 TCP http > 34228 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=7061180 TSER=99926310 WS=1
235.825236 10.0.0.126 -> 10.0.0.123 TCP 34228 > http [ACK] Seq=1 Ack=1 Win=5856 Len=0 TSV=99926311 TSER=7061180
235.825273 10.0.0.126 -> 10.0.0.123 TCP 34228 > http [FIN, ACK] Seq=1 Ack=1 Win=5856 Len=0 TSV=99926311 TSER=7061180
235.825721 10.0.0.123 -> 10.0.0.126 TCP http > 34228 [ACK] Seq=1 Ack=2 Win=5792 Len=0 TSV=7061180 TSER=99926311
235.825722 10.0.0.123 -> 10.0.0.126 TCP http > 34228 [FIN, ACK] Seq=1 Ack=2 Win=5792 Len=0 TSV=7061180 TSER=99926311
235.825756 10.0.0.126 -> 10.0.0.123 TCP 34228 > http [ACK] Seq=2 Ack=2 Win=5856 Len=0 TSV=99926311 TSER=7061180
$ uname -a
Linux gaia.mn.ca 2.6.23.17-88.fc7 #1 SMP Thu May 15 00:35:10 EDT 2008 i686 i686 i386 GNU/Linux
$ ip route get 10.0.0.123
10.0.0.123 dev eth0 src 10.0.0.126
cache mtu 1500 advmss 1460 hoplimit 64
绑定连接的代码:
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv)
{
struct sockaddr_in sn;
socklen_t sn_len;
struct sockaddr_in src;
struct sockaddr_in dst;
int sock;
char b1[INET_ADDRSTRLEN];
char b2[INET_ADDRSTRLEN];
char b3[INET_ADDRSTRLEN];
src.sin_family = dst.sin_family = AF_INET;
src.sin_port = 0;
dst.sin_port = htons(80);
if (argc < 3) {
printf("missing argument\n");
return 1;
}
if (inet_pton(AF_INET, argv[1], &dst.sin_addr) != 1) {
perror("pton");
return -errno;
}
if (inet_pton(AF_INET, argv[2], &src.sin_addr) != 1) {
perror("pton");
return -errno;
}
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket");
return -errno;
}
if (bind(sock, (struct sockaddr*)&src, sizeof src) != 0) {
perror("bind");
return -errno;
}
sn_len = sizeof sn;
if (getsockname(sock, (struct sockaddr*)&sn, &sn_len) != 0) {
perror("getsockname");
return -errno;
}
printf("Bound socket: %s [%s->%s]\n",
inet_ntop(AF_INET, &sn.sin_addr, b1, sizeof b1),
inet_ntop(AF_INET, &src.sin_addr, b2, sizeof b2),
inet_ntop(AF_INET, &dst.sin_addr, b3, sizeof b3));
if (connect(sock, (struct sockaddr*)&dst, sizeof dst) != 0) {
perror("connect");
return -errno;
}
close(sock);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
序列号中的结构sockaddr_;
socklen_t snu len;
src中的结构sockaddr_;
dst中的结构sockaddr_;
int袜子;
字符b1[INET_ADDRSTRLEN];
字符b2[INET_ADDRSTRLEN];
字符b3[INET_ADDRSTRLEN];
src.sin_family=dst.sin_family=AF_INET;
src.sin_端口=0;
dst.sin_端口=htons(80);
如果(argc<3){
printf(“缺少参数\n”);
返回1;
}
if(inet\u pton(AF\u inet,argv[1],&dst.sin\u addr)!=1){
佩罗尔(“普顿”);
返回-错误号;
}
if(inet\u pton(AF\u inet,argv[2],&src.sin\u addr)!=1){
佩罗尔(“普顿”);
返回-错误号;
}
sock=socket(AF\u INET,sock\u STREAM,0);
if(sock<0){
佩罗(“插座”);
返回-错误号;
}
if(绑定(sock,(struct sockaddr*)&src,sizeof src)!=0){
佩罗(“绑定”);
返回-错误号;
}
sn_len=sn的尺寸;
if(getsockname(sock,(struct sockaddr*)和序号及序号)!=0){
perror(“getsockname”);
返回-错误号;
}
printf(“绑定套接字:%s[%s->%s]\n”,
inet\u ntop(AF\u inet和sn.sin\u addr,b1,b1尺寸),
inet_ntop(AF_inet和src.sin_addr、b2、b2尺寸),
inet_ntop(AF_inet和dst.sin_addr,b3,sizeof b3));
if(connect(sock,(struct sockaddr*)和dst,sizeof dst)!=0){
perror(“连接”);
返回-错误号;
}
关闭(袜子);
返回0;
}
问题是我用iptables设置了一个nat后路由规则,即
Chain POSTROUTING (policy ACCEPT 11 packets, 637 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- any eth0.894 anywhere anywhere
一旦我删除了这条规则:
$ sudo iptables -t nat -F
事情又开始起作用了。不久前,我在测试另一个问题时设置了nat规则,但后来忘了删除它。您能解释一下“不再工作”是什么意思吗?在上面代码的每个不同运行中,您的程序都不会打印任何错误,这意味着它实际上已连接并关闭。“绑定套接字”打印行似乎与相应的命令行匹配。数据包跟踪似乎是一个3路握手,然后是一个正常的闭合序列。换句话说,我看不出有什么不对。但我可能遗漏了一些微妙的东西。对不起,我应该使用比.120/.220更不同的源IP。“不工作”情况是从错误的源IP发送,例如绑定到.120,从.220发送流量。您是否从VM运行?如果是这样,您的数据包跟踪是在虚拟机内运行还是在主机上运行?@selbie-谢谢您的关注。原来我用iptables nat规则做了错事。
$ sudo iptables -t nat -F