#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/param.h>
#include <sys/wait.h>
#include <errno.h>
#include <paths.h>
#include <sys/syscall.h>
#include <sys/resource.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/route.h>
#define PROCNET_ROUTE_PATH "/proc/net/route"
#define PROCNET_IFINET6_PATH "/proc/net/if_inet6"
#define SCOPE_LINK_STR "fe80"
int net_get_ipv6_ifaddr(char type, const char *ifname, char *addr, int length, char *prefix, int length2)
{
int ret = 0;
FILE *fp;
char addr6[46] = {0}, dev_name[20] = {0};
char addr6p[8][5];
int length_of_prefix, scope_value, if_flags, if_index;
struct sockaddr_in6 sap = {0};
if (!ifname || !addr || length <= 0 || !prefix || length2 <= 0)
return -1;
fp = fopen(PROCNET_IFINET6_PATH, "r");
if (!fp) return -1;
lockf(fileno(fp), F_LOCK, 0);
while (fscanf(fp, "%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_index, &length_of_prefix, &scope_value, &if_flags, dev_name) != EOF) {
if (!strcmp(dev_name, ifname)) {
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]);
if (strncmp(addr6p[0], SCOPE_LINK_STR, strlen(SCOPE_LINK_STR)) == 0) {
//fe80 Scope:Link
if (type == 1) {
inet_pton(AF_INET6, addr6, &sap.sin6_addr);
inet_ntop(AF_INET6, &sap.sin6_addr, addr, length);
snprintf(prefix, length2, "%d", length_of_prefix);
lockf(fileno(fp), F_ULOCK, 0);
fclose(fp);
return 0;
}
} else {
//2001 Scope:Global
if (type == 0) {
inet_pton(AF_INET6, addr6, &sap.sin6_addr);
inet_ntop(AF_INET6, &sap.sin6_addr, addr, length);
snprintf(prefix, length2, "%d", length_of_prefix);
lockf(fileno(fp), F_ULOCK, 0);
fclose(fp);
return 0;
}
}
}
}
lockf(fileno(fp), F_ULOCK, 0);
fclose(fp);
return -1;
}
int net_get_ipv6_gateway(char type, const char *ifname, char *gateway, int length)
{
FILE *fp;
char buffer[80] = {'\0'};
char path[128] = {'\0'};
char flag = 0;
char *dfstr = "default via ";// "default via ";
char *p, *q;
if (!ifname || !gateway || length <= 0)
return -1;
//snprintf(path, sizeof(path), "/bin/ip -6 route show dev %s", ifname);
snprintf(path, sizeof(path), "ip -6 route show dev %s", ifname);//hi3798 have not /bin/ip
fp = popen(path, "r");
if (!fp) return -1;
lockf(fileno(fp), F_LOCK, 0);
while (fgets(buffer, sizeof(buffer), fp)) {
if (!strncmp(buffer, dfstr, strlen(dfstr))) {
p = (char *)&buffer[strlen(dfstr)];
if (p) {
q = strchr(p, ' ');
if (q) {
if (type == 1) {
if (strncmp(p, SCOPE_LINK_STR, strlen(SCOPE_LINK_STR)) == 0) {
snprintf(gateway, (int)(q - p + 1), "%s", p);
lockf(fileno(fp), F_ULOCK, 0);
pclose(fp);
return 0;
}
} else {
snprintf(gateway, (int)(q - p + 1), "%s", p);
lockf(fileno(fp), F_ULOCK, 0);
pclose(fp);
return 0;
}
}
}
}
}
lockf(fileno(fp), F_ULOCK, 0);
pclose(fp);
return -1;
}
int net_is_validipv6(const char *hostname)
{
struct sockaddr_in6 addr;
if (!hostname) return -1;
if (strchr(hostname, '.')) return -1;//暂时排除::ffff:204.152.189.116
if (inet_pton(AF_INET6, hostname, &addr.sin6_addr) != 1) return -1;
return 0;
}
int net_ipv4_trans_ipv6(const char *source, char *dest, int length)
{
if (!source || !dest || length <= 0)
return -1;
if (strncmp(source, "::ffff:", strlen("::ffff:")) == 0 && strchr(source, '.')) {
char ipv4[32] = {0};
snprintf(ipv4, sizeof(ipv4), "%s", source+strlen("::ffff:"));
struct in_addr s4 = {0};
if (inet_pton(AF_INET, ipv4, (void*)&s4) != 1)
return -1;
char s6[4] = {0};
s6[0] = s4.s_addr&0xff;
s6[1] = s4.s_addr>>8&0xff;
s6[2] = s4.s_addr>>16&0xff;
s6[3] = s4.s_addr>>24&0xff;
snprintf(dest, length, "::ffff:%x%.2x:%x%.2x", s6[0]&0xff, s6[1]&0xff, s6[2]&0xff, s6[3]&0xff);
return 0;
}
return -1;
}
int main(int argc, char *argv[])
{
int ret = 0;
char ipv6[64] = {0};
ret = net_ipv4_trans_ipv6(argv[1], ipv6, sizeof(ipv6));
printf("ret = %d ipv6 = %s\n", ret, ipv6);
char type=1;
char *ifname="eth0";
char addr[64] = {0};
int length=64;
char prefix[32]={0};
int length2=32;
net_get_ipv6_ifaddr(type,ifname,addr,length,prefix,length2);
printf("addr=%s\n",addr);
printf("prefix=%s\n",prefix);
char gateway[64] = {0};
type=0; //外网
net_get_ipv6_gateway(type,ifname,gateway,length);
printf("gateway=%s\n",gateway);
return ret;
}
执行:
./ip6 ::ffff:192.168.1.181