如何获取网络协议的协议号
网络层中的IP数据报的首部有一个协议
字段。占8位。用来标识数据报中的报文使用何种协议。以便使目的主机的IP层知道应将报文数据上交给哪个处理过程。我们常用到的tcp协议的协议号为6,UDP为17,ICMP为1等。本机主机在/etc/protocols
的协议数据库文件中保存了协议名与协议号之间的映射表。可以使用命令cat /etc/protocols
查看。
linux使用结构体struct protoent
表示协议的映射信息。struct protoent
各个成员的含义如下:
struct protoent {
char *p_name; // 官方名称
char **p_aliases; // 所有别名构成的字符串数组。最后以一个字符串为NULL,用于判断数组的结束。
int p_proto; // 协议号
}
下面是获取协议信息的相关函数,使用时需要包含netdb.h
头文件:
struct protoent *getprotobyname(const char *name)
- 通过协议名称获取指定网络协议的信息体。
- name:协议名。如"tcp".
- return:成功返回信息体指针,失败返回NULL.
struct protoent *getprotobynumber(int proto)
- 通过协议号获取指定网络协议的信息体。
- proto:协议号。如6.
读取协议数据库相关的函数:
void setprotoent(int stayopen)
- 打开协议数据库。并设置起始值。
struct protoent *getprotoent(void)
- 浏览数据库。获取服务数据库中的下一个条目。
void endprotoent(void)
- 关闭数据库。
使用例程如下:
#include <stdio.h>
#include <netdb.h>
void main(void)
{
struct protoent *pInfo;
pInfo = getprotobyname("tcp");
printf("%s:%d\n",pInfo->p_name,pInfo->p_proto);
printf("别名:");
for(int i = 0; pInfo->p_aliases[i];i++){
printf("%s ",pInfo->p_aliases[i]);
}
printf("\n");
//读取协议数据库
setprotoent(0);
int index = 0;
while(1){
pInfo = getprotoent();
if(pInfo == NULL){
break;
}
printf("[%2d]%s:%d\n",++index,pInfo->p_name,pInfo->p_proto);
}
endprotoent();
}
此处后的文字已经和题目内容无关,可以不看。
qq群:825695030
微信公众号:嵌入式的日常
如果上面的文章对你有用,欢迎打赏、点赞、评论。