套接字 – 使用辅助IP地址连接套接字
不久前,我能够通过以下步骤从给定接口上的主要或辅助IP地址连接到给定目标地址.
>使用ip addr add …为给定的接口添加辅助IP地址, 我最近将一台机器升级到Linux 3.3.6,这不再有效,但我不记得我试过的最后一个版本实际上是在工作.有谁知道如何在较新的内核中做同样的事情?我刚刚在另一台机器上验证了2.6.23上的相同代码.
这是当我在3.3.6(在后台运行的tshark的数据包捕获输出)上运行代码(源端)时发生的情况: $./bind_connect 10.0.1.124 10.0.1.120 Bound socket: 10.0.1.120 [10.0.1.120->10.0.1.124] # wrong source IP (should use 10.0.1.120 from bind) # | # v $121.051052 10.0.1.220 -> 10.0.1.124 50418 80 TCP 74 50418 > 80 [SYN] Seq=3358582895 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=30589624 TSecr=0 WS=128 121.051428 10.0.1.124 -> 10.0.1.220 80 50418 TCP 74 80 > 50418 [SYN,ACK] Seq=1815118993 Ack=3358582896 Win=5792 Len=0 MSS=1460 SACK_PERM=1 TSval=8157158 TSecr=30589624 WS=2 121.051475 10.0.1.220 -> 10.0.1.124 50418 80 TCP 66 50418 > 80 [ACK] Seq=3358582896 Ack=1815118994 Win=14720 Len=0 TSval=30589624 TSecr=8157158 121.051504 10.0.1.220 -> 10.0.1.124 50418 80 TCP 66 50418 > 80 [FIN,ACK] Seq=3358582896 Ack=1815118994 Win=14720 Len=0 TSval=30589624 TSecr=8157158 121.051768 10.0.1.124 -> 10.0.1.220 80 50418 TCP 66 80 > 50418 [ACK] Seq=1815118994 Ack=3358582897 Win=5792 Len=0 TSval=8157158 TSecr=30589624 121.051913 10.0.1.124 -> 10.0.1.220 80 50418 TCP 66 80 > 50418 [FIN,ACK] Seq=1815118994 Ack=3358582897 Win=5792 Len=0 TSval=8157158 TSecr=30589624 121.051941 10.0.1.220 -> 10.0.1.124 50418 80 TCP 66 50418 > 80 [ACK] Seq=3358582897 Ack=1815118995 Win=14720 Len=0 TSval=30589625 TSecr=8157158 $./bind_connect 10.0.1.124 10.0.1.220 Bound socket: 10.0.1.220 [10.0.1.220->10.0.1.124] $124.139966 10.0.1.220 -> 10.0.1.124 41470 80 TCP 74 41470 > 80 [SYN] Seq=1404133303 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=30590551 TSecr=0 WS=128 124.140421 10.0.1.124 -> 10.0.1.220 80 41470 TCP 74 80 > 41470 [SYN,ACK] Seq=1918490481 Ack=1404133304 Win=5792 Len=0 MSS=1460 SACK_PERM=1 TSval=8157467 TSecr=30590551 WS=2 124.140478 10.0.1.220 -> 10.0.1.124 41470 80 TCP 66 41470 > 80 [ACK] Seq=1404133304 Ack=1918490482 Win=14720 Len=0 TSval=30590551 TSecr=8157467 124.140553 10.0.1.220 -> 10.0.1.124 41470 80 TCP 66 41470 > 80 [FIN,ACK] Seq=1404133304 Ack=1918490482 Win=14720 Len=0 TSval=30590551 TSecr=8157467 124.140934 10.0.1.124 -> 10.0.1.220 80 41470 TCP 66 80 > 41470 [ACK] Seq=1918490482 Ack=1404133305 Win=5792 Len=0 TSval=8157467 TSecr=30590551 124.140976 10.0.1.124 -> 10.0.1.220 80 41470 TCP 66 80 > 41470 [FIN,ACK] Seq=1918490482 Ack=1404133305 Win=5792 Len=0 TSval=8157467 TSecr=30590551 124.140995 10.0.1.220 -> 10.0.1.124 41470 80 TCP 66 41470 > 80 [ACK] Seq=1404133305 Ack=1918490483 Win=14720 Len=0 TSval=30590551 TSecr=8157467 $uname -a Linux erebus.mn.ca 3.3.6-1-ARCH #1 SMP PREEMPT Sun May 13 09:59:18 UTC 2012 i686 GNU/Linux $ip route get 10.0.1.124 10.0.1.124 dev eth0.894 src 10.0.1.220 cache ipid 0x61ca rtt 3ms rttvar 3ms cwnd 10 然后在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 bind_connect的代码: #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 argumentn"); 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),&src.sin_addr,b2,sizeof b2),&dst.sin_addr,b3,sizeof b3)); if (connect(sock,(struct sockaddr*)&dst,sizeof dst) != 0) { perror("connect"); return -errno; } close(sock); return 0; } 解决方法
问题是我用iptables建立了一个nat POSTROUTING规则,即
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规则,然后忘了将其删除. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |