IPV6地址处理小结
1、地址转换
1、网路地址转化函数inet_pton和inet_ntop
这两个函数是随IPv6出现的函数,对于IPv4地址和IPv6地址都适用,函数中p和n分别代表表达(presentation)和数值(numeric)。地址的表达格式通常是ASCII字符串,数值格式则是存放到套接字地址结构的二进制值。
#include <arpe/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr); //将点分十进制的ip地址转化为用于网络传输的数值格式返回值:若成功则为1,若输入不是有效的表达式则为0,若出错则为-1const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len); //将数值格式转化为点分十进制的ip地址格式返回值:若成功则为指向结构的指针,若出错则为NULL
(1)这两个函数的family参数既可以是AF_INET(ipv4)也可以是AF_INET6(ipv6)。如果,以不被支持的地址族作为family参数,这两个函数都返回一个错误,并将errno置为EAFNOSUPPORT.
(2)第一个函数尝试转换由strptr指针所指向的字符串,并通过addrptr指针存放二进制结果,若成功则返回值为1,否则如果所指定的family而言输入字符串不是有效的表达式格式,那么返回值为0.
(3)inet_ntop进行相反的转换,从数值格式(addrptr)转换到表达式(strptr)。inet_ntop函数的strptr参数不可以是一个空指针。调用者必须为目标存储单元分配内存并指定其大小,调用成功时,这个指针就是该函数的返回值。len参数是目标存储单元的大小,以免该函数溢出其调用者的缓冲区。如果len太小,不足以容纳表达式结果,那么返回一个空指针,并置为errno为ENOSPC。
int getsockname(int sockfd, struct sockaddr *localaddr,socklen_t *addrlen);
int getpeername(int sockfd, struct sockaddr *localaddr,socklen_t *addrlen);
getsockname可以获得一个与sockfd相关的本地地址。
getpeername可以获得一个与sockfd相关的对端地址。
2、地址格式
sa_family_t 通常为8位无符号整数
in_port_t TCP或UDP端口,一般为uint16_t
sockaddr和sockaddr_in开头一样,内存大小也一样,可以互相转换。
在使用bind或accept时,虽然参数为struct sockaddr *addr,但是可以取sockaddr_in6类型的地址,通过传递地址和长度socklen_t addrlen来进行处理。如果是IPV6操作,则socklen_t addrlen长度为sizeof(struct sockaddr_in6)。在使用inet_pton和inet_ntop时也有类似问题。
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
typedef unsigned short int sa_family_t/* Structure describing a generic socket address. */
struct sockaddr
{uint8_t sa_len;sa_family_t sa_family; /* Common data: address family and length. */char sa_data[14]; /* Address data. */
};/* /usr/include/netinet/in.h */
/* Structure describing an Internet socket address. */
struct sockaddr_in
{uint8_t sin_len;sa_family_t sin_family; in_port_t sin_port; /* Port number. */struct in_addr sin_addr; /* Internet address. *//* Pad to size of `struct sockaddr'. */unsigned char sin_zero[8];
};typedef uint32_t in_addr_t;
struct in_addr{in_addr_t s_addr;};struct sockaddr_in6
{uint8_t sin6_len;sa_family_t sin6_family; in_port_t sin6_port; /* Transport layer port # */uint32_t sin6_flowinfo; /* IPv6 flow information */struct in6_addr sin6_addr; /* IPv6 address */uint32_t sin6_scope_id; /* IPv6 scope-id */
};struct in6_addr{uint8_t s6_addr[16];};
3、IPV6绑定时报错处理
local_addr和local_port确定本地的IPV6地址和端口号,在bind时报错,检查IPV6地址和端口号均无问题,后来检查发现绑定IPV6地址时,需要指定sin6_scope_id,可以通过if_nametoindex查询到端口名称对应的索引。
Cannot bind socket (Cannot assign requested address)
struct sockaddr_in6 src;
int sock;
int opt = 1;
struct in6_addr ipv6_inaddr;
bzero(&src, sizeof(src));if ((sock = socket(AF_INET6, SOCK_STREAM, 0)) <= 0)
{printf("open Socket error (%s)\n", strerror(errno));return 0;
}src.sin6_family = AF_INET6;
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if(ret == -1)
{printf("setsockopt fail %s\n", strerror(errno));return 0;
}/* bind socket */
src.sin6_family = AF_INET6;
src.sin6_port = htons((unsigned short) local_port); /* short, network byte order */if(inet_pton(AF_INET6,local_addr,(void *)&ipv6_inaddr)!=1)
{printf("Cannot conver local_addr %s, error %s\n", local_addr, strerror(errno));src.sin6_addr = in6addr_any; //
}
else
{src.sin6_addr = ipv6_inaddr;
}src.sin6_scope_id = interface;if (bind(sock, (struct sockaddr *) &src, sizeof(struct sockaddr_in6)) == -1)
{printf("Cannot bind socket (%s)\n", strerror(errno)); return 0;
}
#include <net/if.h>unsigned if_nametoindex(const char *ifname);
char *if_indextoname(unsigned ifindex, char *ifname);
struct if_nameindex *if_nameindex(void);
void if_freenameindex(struct if_nameindex *ptr);/*
if_nametoindex():指定网络接口名称字符串作为参数;若该接口存在,则返回相应的索引,否则返回0if_indextoname():指定网络接口索引以及一块长度至少为IF_NAMESIZE(16)字节的内存区域作为参数;若索引对应的网络接口存在,则在内存区域中返回该接口的名称字符串,否则返回NULL,并将errno设置为相应的值if_nameindex():返回动态分配的struct if_nameindex结构数组,数组中的每一个元素分别对应一个本地网络接口;struct if_nameindex结构的if_index字段为接口索引,if_name字段为接口名称字符串;索引为0且名称字符串为NULL表示结构数组的末尾;调用出错时,返回NULL,并将errno设置为相应的值if_freenameindex():通过if_nameindex()获取完毕接口名称与索引后,调用该函数以释放动态分配的内存区域以上4个函数在系统的man文档中都可以查看相应的描述,且都是POSIX标准支持的,Linux内核可能未实现这些函数,或已实现但不同于POSIX标准。这些函数的原型声明与定义并未出现在CentOS 6.7的定制内核2.6.32-573.26.1.el6.x86_64以及原版内核2.6.32.5中,而是由系统的glibc-2.12实现:在glibc-2.12.2源码树中,函数的原型声明位于sysdeps/gnu/net/if.h与sysdeps/generic/net/if.h,函数的定义位于sysdeps/unix/sysv/linux/if_index.c中,本质上是对ioctl(2)的SIOCGIFNAME,SIOCGIFCONF,SIOCGIFINDEX等操作以及netlink套接字进行了封装
*/
IPV6地址处理小结相关推荐
- ipv6 over gre/sit: 通过 6in4 获得 ipv6 地址
ipv6 over gre/sit: 通过 6in4 获得 ipv6 地址 发表于 2019-01-17 更新于 2020-07-02 分类于 ipv6 over ipv4 , tunnel , gr ...
- IPv6基础-IPv6地址
IPv6地址:128bit,16个字节. 1 三类表示方法 首选格式.压缩格式.特殊格式 (1)首选格式:X:X:X:X:X:X:X:X,8个16bit段,前导零可以删除,但是每段要有一个数字: 举例 ...
- IPv6地址分类及表示方法
对于IPv4地址,我们知道分为A类.B类.C类.组播地址和留用地址,几大类,ABC类地址中还会有不同功能的如广播地址.私有地址等类型.那么IPv6的地址是怎么分类的呢?本文就带大家初步了解一下. 先说 ...
- 微指令地址的形成方式_交换那些事儿 | 基础维护篇 IPv6地址分类及配置方法
IPv6地址分类及配置方法 H3C交换机基础维护篇 何为IPv6 随着网络的不断扩大和发展,IPv4的地址空间已不能满足需求,因此IPv6协议的应用越来越广泛.那么IPv6地址是如何规范和配置的呢,今 ...
- Linux IPv6 地址配置
添加IPV6地址 ip -6 addr add <ipv6address>/<prefixlength> dev <interface> ip -6 addr ad ...
- ENGINEER 003:配置IPv6地址
配置IPv6地址 (简单)---不再玩ipv4了 IPv4和IPv6的区别? Ipv4不够用了,就推行Ipv6.IPv6迟迟没有得到推广? IPv4有个技术叫nat,地址转换,最大化节约了IP地 ...
- 解决苹果APP审核需要的IPv6地址的问题
解决苹果APP审核需要的IPv6地址的问题 参考文章: (1)解决苹果APP审核需要的IPv6地址的问题 (2)https://www.cnblogs.com/randytech/p/7016709. ...
- 提取IPv6地址的编码信息
提取IPv6地址的编码信息 为了保持兼容和地址转化,很多IPv6地址将额外的信息编码到地址信息中,如IPv4地址和Mac地址.在Nmap中,可以使用address-info脚本提取内嵌的信息,并进行解 ...
- 本地win7ping VM linux ipv6地址问题
前述 在windows和linux同时安装ipv6之后,系统将会自动分配一个link-local(链接本地)地址 也就是ifconfig -a看到的一行[inet6 addr: fe80::20c:2 ...
最新文章
- ESXi安装全过程及基本配置
- 右脑编程法--左脑是基础(4)之语言篇
- 拦截锚点修改url_前端系列课程(2)-网络基础概念(URL)
- 11. Java基础之继承
- 论文笔记(eTrust: Understanding Trust Evolution in an Online World)
- k近邻分类器的使用:简单例子
- mongodb-查询
- rpm deb命令集合
- 线性表的链式存储——单链表的遍历与优化
- 【优化算法】蛾群优化算法(MSA)【含Matlab源码 1807期】
- 计算机网络实验:netmeeting 在局域网上的应用
- ERP原理与应用教程-第一章
- 最全的搜索引擎入口和分类目录入口
- 基于Python的MACD顶底背离形态的实现
- 密码框password调用数字键盘
- grpc双向流 python_gRPC Golang/Python使用
- 服务端开发or客户端开发的选择
- 表格一分为二html,如何在excel表中的将一个格子一分为二
- 前端 115道 面试题总结【持续更新...】
- vscode代码拼写检查插件的使用(超详细)