📄 ipv6addr.c
字号:
addr6p[4], addr6p[5], addr6p[6], addr6p[7], &if_idx, &plen, &scope, &dad_status, devname) != EOF){ int i; int n; int s; gboolean same = TRUE; sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]); /* Only Global address entry would be considered. * maybe change? */ if (0 != scope) { continue; } /* If specified prefix, only same prefix entry * would be considered. */ if (*plen_target!=0 && plen != *plen_target) { continue; } *plen_target = plen; /* Convert string to sockaddr_in6 */ inet_pton(AF_INET6, addr6, &addr); /* Make the mask based on prefix length */ for (i = 0; i < 16; i++) { mask.s6_addr[i] = 0; } n = plen / 8; for (i = 0; i < n+1; i++) { mask.s6_addr[i] = 0xFF; } s = 8 - plen % 8; mask.s6_addr[n]<<=s; /* compare addr and addr_target */ same = TRUE; for (i = 0; i < 16; i++) { if ((addr.s6_addr[i]&mask.s6_addr[i]) != (addr_target->s6_addr[i]&mask.s6_addr[i])) { same = FALSE; break; } } /* We found it! */ if (same) { fclose(f); return devname; } } fclose(f); return NULL;}/* get the device name and the plen_target of a special address */char*get_if(struct in6_addr* addr_target, int* plen_target){ FILE *f; char addr6[40]; static char devname[20]=""; struct in6_addr addr; unsigned int plen, scope, dad_status, if_idx; char addr6p[8][5]; /* open /proc/net/if_inet6 file */ if ((f = fopen(IF_INET6, "r")) == NULL) { return NULL; } /* loop for each entry */ while ( fscanf(f,"%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7], &if_idx, &plen, &scope, &dad_status, devname) != EOF) { sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]); /* Only Global address entry would be considered. * maybe change */ if (0 != scope) { continue; } /* "if" specified prefix, only same prefix entry * would be considered. */ if (*plen_target!=0 && plen != *plen_target) { continue; } *plen_target = plen; /* Convert to sockaddr_in6 */ inet_pton(AF_INET6, addr6, &addr); /* We found it! */ if (0 == memcmp(&addr, addr_target,sizeof(addr))) { fclose(f); return devname; } } fclose(f); return NULL;}intassign_addr6(struct in6_addr* addr6, int prefix_len, char* if_name){ struct in6_ifreq ifr6; /* Get socket first */ int fd; struct ifreq ifr; fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) { return 1; } /* Query the index of the if */ strcpy(ifr.ifr_name, if_name); if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { return -1; } /* Assign the address to the if */ ifr6.ifr6_addr = *addr6; ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) { return -1; } close (fd); return 0;}intunassign_addr6(struct in6_addr* addr6, int prefix_len, char* if_name){ int fd; struct ifreq ifr; struct in6_ifreq ifr6; /* Get socket first */ fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) { return 1; } /* Query the index of the if */ strcpy(ifr.ifr_name, if_name); if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { return -1; } /* Unassign the address to the if */ ifr6.ifr6_addr = *addr6; ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) { return -1; } close (fd); return 0;}intis_addr6_available(struct in6_addr* addr6){ struct sockaddr_in6 addr; struct icmp6hdr icmph; u_char outpack[64]; int icmp_sock; int ret; struct iovec iov; u_char packet[64]; struct msghdr msg; struct in6_addr local; icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); icmph.icmp6_type = ICMPV6_ECHO_REQUEST; icmph.icmp6_code = 0; icmph.icmp6_cksum = 0; icmph.icmp6_sequence = htons(0); icmph.icmp6_identifier = 0; memcpy(&outpack, &icmph, sizeof(icmph)); memset(&addr, 0, sizeof(struct sockaddr_in6)); addr.sin6_family = AF_INET6; addr.sin6_port = htons(IPPROTO_ICMPV6); memcpy(&addr.sin6_addr,addr6,sizeof(struct in6_addr)); ret = sendto(icmp_sock, (char *)outpack, 64, 0, (struct sockaddr *) &addr, sizeof(struct sockaddr_in6)); if (0 >= ret) { return -1; } iov.iov_base = (char *)packet; iov.iov_len = 64; /* This should be a system #define */ msg.msg_name = &addr; msg.msg_namelen = sizeof(addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; ret = recvmsg(icmp_sock, &msg, MSG_DONTWAIT); if (0 >= ret) { return -1; } inet_pton(AF_INET6, "::1", &local); if (0 != memcmp(&local, &addr.sin6_addr,sizeof(local))) { return -1; } return 0;}static void usage(const char* self){ printf("usage: %s ipv6-address {start|stop|status|monitor}\n",self); return;}/* Following code is copied from send_arp.c, linux-HA project. */voidbyebye(int nsig){ (void)nsig; /* Avoid an "error exit" log message if we're killed */ exit(0);}intcreate_pid_directory(const char *pid_file){ int status; struct stat stat_buf; char* dir; dir = strdup(pid_file); if (!dir) { cl_log(LOG_INFO, "Memory allocation failure: %s\n", strerror(errno)); return -1; } dirname(dir); status = stat(dir, &stat_buf); if (status < 0 && errno != ENOENT && errno != ENOTDIR) { cl_log(LOG_INFO, "Could not stat pid-file directory " "[%s]: %s", dir, strerror(errno)); free(dir); return -1; } if (!status) { if (S_ISDIR(stat_buf.st_mode)) { return 0; } cl_log(LOG_INFO, "Pid-File directory exists but is " "not a directory [%s]", dir); free(dir); return -1; } if (mkdir(dir, S_IRUSR|S_IWUSR|S_IXUSR | S_IRGRP|S_IXGRP) < 0) { cl_log(LOG_INFO, "Could not create pid-file directory " "[%s]: %s", dir, strerror(errno)); free(dir); return -1; } return 0;}intwrite_pid_file(const char *pid_file){ int pidfilefd; char pidbuf[11]; unsigned long pid; ssize_t bytes; if (*pid_file != '/') { cl_log(LOG_INFO, "Invalid pid-file name, must begin with a " "'/' [%s]\n", pid_file); return -1; } if (create_pid_directory(pid_file) < 0) { return -1; } while (1) { pidfilefd = open(pid_file, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR); if (pidfilefd < 0) { if (errno != EEXIST) { /* Old PID file */ cl_log(LOG_INFO, "Could not open pid-file " "[%s]: %s", pid_file, strerror(errno)); return -1; } } else { break; } pidfilefd = open(pid_file, O_RDONLY, S_IRUSR|S_IWUSR); if (pidfilefd < 0) { cl_log(LOG_INFO, "Could not open pid-file " "[%s]: %s", pid_file, strerror(errno)); return -1; } while (1) { bytes = read(pidfilefd, pidbuf, sizeof(pidbuf)-1); if (bytes < 0) { if (errno == EINTR) { continue; } cl_log(LOG_INFO, "Could not read pid-file " "[%s]: %s", pid_file, strerror(errno)); return -1; } pidbuf[bytes] = '\0'; break; } if(unlink(pid_file) < 0) { cl_log(LOG_INFO, "Could not delete pid-file " "[%s]: %s", pid_file, strerror(errno)); return -1; } if (!bytes) { cl_log(LOG_INFO, "Invalid pid in pid-file " "[%s]: %s", pid_file, strerror(errno)); return -1; } close(pidfilefd); pid = strtoul(pidbuf, NULL, 10); if (pid == ULONG_MAX && errno == ERANGE) { cl_log(LOG_INFO, "Invalid pid in pid-file " "[%s]: %s", pid_file, strerror(errno)); return -1; } if (kill(pid, SIGKILL) < 0 && errno != ESRCH) { cl_log(LOG_INFO, "Error killing old proccess [%lu] " "from pid-file [%s]: %s", pid, pid_file, strerror(errno)); return -1; } cl_log(LOG_INFO, "Killed old send_arp process [%lu]\n", pid); } if (snprintf(pidbuf, sizeof(pidbuf), "%u" , getpid()) >= (int)sizeof(pidbuf)) { cl_log(LOG_INFO, "Pid too long for buffer [%u]", getpid()); return -1; } while (1) { bytes = write(pidfilefd, pidbuf, strlen(pidbuf)); if (bytes != strlen(pidbuf)) { if (bytes < 0 && errno == EINTR) { continue; } cl_log(LOG_INFO, "Could not write pid-file " "[%s]: %s", pid_file, strerror(errno)); return -1; } break; } close(pidfilefd); return 0;}static intmeta_data_addr6(void){ const char* meta_data= "<?xml version=\"1.0\"?>\n" "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" "<resource-agent name=\"IPv6addr\" version=\"0.1\">\n" " <version>1.0</version>\n" " <parameters>\n" " <parameter name=\"ipv6addr\" unique=\"0\">\n" " <longdesc lang=\"en\">\n" " This script manages IPv6 alias IPv6 addresses,It can add an IP6\n" " alias, or remove one.\n" " </longdesc>\n" " <shortdesc lang=\"en\">manages IPv6 alias</shortdesc>\n" " <content type=\"string\" default=\"\" />\n" " </parameter>\n" " </parameters>\n" " <actions>\n" " <action name=\"start\" timeout=\"15\" />\n" " <action name=\"stop\" timeout=\"15\" />\n" " <action name=\"status\" timeout=\"15\" interval=\"15\" start-delay=\"15\" />\n" " <action name=\"monitor\" timeout=\"15\" interval=\"15\" start-delay=\"15\" />\n" " <action name=\"meta-data\" timeout=\"5\" />\n" " </actions>\n" "</resource-agent>\n"; printf("%s\n",meta_data); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -