双机热备中解决IP漂移后arp表不更新
2012-03-15 17:35
375 查看
方案一 ip漂移后向用这个IP向该网段发送arp广播,促使arp表更新
方案二 用一个备用mac,ip漂移的时候连同mac一起漂移
方案二 用一个备用mac,ip漂移的时候连同mac一起漂移
#include <iostream> #include <sys/socket.h> #include <sys/ioctl.h> #include <netinet/if_ether.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/udp.h> #include <netinet/tcp.h> #include <net/if.h> #include <memory.h> #include <arpa/inet.h> using namespace std; enum { ARP_MSG_SIZE = 0x2a }; char * strncpy_IFNAMSIZ(char * dst, const char * src) { # ifndef IFNAMSIZ enum { IFNAMSIZ = 16 }; # endif return strncpy(dst, src, IFNAMSIZ); } struct arpMsg { /* Ethernet header */ uint8_t h_dest[6]; /* 00 destination ether addr */ uint8_t h_source[6]; /* 06 source ether addr */ uint16_t h_proto; /* 0c packet type ID field */ /* ARP packet */ uint16_t htype; /* 0e hardware type (must be ARPHRD_ETHER) */ uint16_t ptype; /* 10 protocol type (must be ETH_P_IP) */ uint8_t hlen; /* 12 hardware address length (must be 6) */ uint8_t plen; /* 13 protocol address length (must be 4) */ uint16_t operation; /* 14 ARP opcode */ uint8_t sHaddr[6]; /* 16 sender's hardware address */ uint8_t sInaddr[4]; /* 1c sender's IP address */ uint8_t tHaddr[6]; /* 20 target's hardware address */ uint8_t tInaddr[4]; /* 26 target's IP address */ uint8_t pad[18]; /* 2a pad for min. ethernet payload (60 bytes) */ } PACKED; const int const_int_1 = 1; int setsockopt_broadcast(int fd) { return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1)); } char * safe_strncpy(char * dst, const char * src, size_t size) { if (!size) return dst; dst[--size] = '/0'; return strncpy(dst, src, size); } int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t * from_mac, const char * interface) { int timeout_ms; int s; int rv = 1; /* "no reply received" yet */ struct sockaddr addr; /* for interface name */ struct arpMsg arp; s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)); if (s == -1) { perror("raw_socket"); return -1; } if (setsockopt_broadcast(s) == -1) { perror("cannot enable bcast on raw socket"); goto ret; } /* send arp request */ memset(&arp, 0, sizeof(arp)); memset(arp. h_dest, 0xff, 6); /* MAC DA */ memcpy(arp. h_source, from_mac, 6); /* MAC SA */ arp. h_proto = htons(ETH_P_ARP); /* protocol type (Ethernet) */ arp. htype = htons(ARPHRD_ETHER); /* hardware type */ arp. ptype = htons(ETH_P_IP); /* protocol type (ARP message) */ arp. hlen = 6; /* hardware address length */ arp. plen = 4; /* protocol address length */ arp. operation = htons(ARPOP_REQUEST); /* ARP op code */ memcpy(arp. sHaddr, from_mac, 6); /* source hardware address */ memcpy(arp. sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */ /* tHaddr is zero-fiiled *//* target hardware address */ memcpy(arp. tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */ memset(&addr, 0, sizeof(addr)); safe_strncpy(addr. sa_data, interface, sizeof(addr. sa_data)); if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0) { // TODO: error message? caller didn't expect us to fail, // just returning 1 "no reply received" misleads it. } ret: close(s); return rv; } int read_interface(const char * interface, int * ifindex, uint32_t * addr, uint8_t * arp) { int fd; struct ifreq ifr; struct sockaddr_in * our_ip; memset(&ifr, 0, sizeof(ifr)); fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); ifr. ifr_addr. sa_family = AF_INET; strncpy_IFNAMSIZ(ifr. ifr_name, interface); if (addr) { if (ioctl(fd, SIOCGIFADDR, &ifr) != 0) { perror("ioctl"); close(fd); return -1; } our_ip = (struct sockaddr_in *) &ifr. ifr_addr; *addr = our_ip-> sin_addr. s_addr; printf("ip of %s = %s \n", interface, inet_ntoa(our_ip-> sin_addr)); } if (ifindex) { if (ioctl(fd, SIOCGIFINDEX, &ifr) != 0) { close(fd); return -1; } printf("adapter index %d", ifr. ifr_ifindex); *ifindex = ifr. ifr_ifindex; } if (arp) { if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0) { close(fd); return -1; } memcpy(arp, ifr. ifr_hwaddr. sa_data, 6); printf("adapter hardware address %02x:%02x:%02x:%02x:%02x:%02x\n", arp[0], arp[1], arp[2], arp[3], arp[4], arp[5]); } close(fd); return 0; } int main(void) { uint32_t TEST_IP = inet_addr("10.192.64.255"); char interface[] = "eth0"; uint32_t ip, t_ip; uint8_t mac[6]; read_interface(interface, NULL, &ip, mac); char buf[128]; strcpy(buf, "ifconfig eth0:1 10.192.64.137 netmask 255.255.255.0"); system(buf); t_ip = inet_addr("10.192.64.137"); for (int i = 0; i < 10; i++) { arpping(TEST_IP, t_ip, mac, interface); usleep(50); } return 0; }
相关文章推荐
- Netbeans国内IP更新、下载插件慢的解决方法(参考之前Android SDK更新慢)
- [bigdata-65] ubuntu 14.04服务器版 keepalived 双机热备ip漂移 python3+flask+gevent的web服务测试
- 2014-10-2 bug更新5 ecshop和ectouch解决动态ip登录超时和购物车清空问题
- openshift registry固定ip不更新问题解决
- mmJ:Linux强制更新Ip地址,解决Ip冲突无法访问问题
- 电脑ip变动导致Android Studio中 SVN无法上传更新项目的解决方法
- 网卡序号漂移的解决办法(复制虚拟机IP问题)
- Xmarks 无法同步的暂时解决办法 ip更新
- 双机热备时如何解决IP重复
- Ubuntu下启用root账户和设置固定IP && ntp解决虚拟机Ubuntu时间与windows时间不同步
- ubuntu 常见问题解决办法 【持续更新】
- python例子-Nmap扫描IP并更新
- tensorflow运行错误及解决方法--一直更新
- “鼠标拖动游戏窗口,消息循环会卡住,导致游戏不能更新不能渲染”,解决办法在这里
- webpack + vue 项目 自定义 插件 解决 前端 JS 版本 更新 问题
- 万网国际中文域名不能访问被指向ip127.0.0.9或搜狗搜索页面解决办法
- centos-6.2安装完后没有eth0网卡,无法设置ip的解决方法
- 解决mac无法更新android sdk报Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xml错误
- 解决被EMOS屏蔽的IP
- 解决更新需要花去 x M 磁盘上总计 /boot 的空间。请在 磁盘上流出 /boot 空间。sudo apt-get clean