怎么将字符串进行网络字节序转换 示例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么将字符串进行网络字节序转换 示例相关的知识,希望对你有一定的参考价值。

参考技术A 现在一般使用inet_aton和inet_ntoa来处理网络字节和主机字节之间的转换;

有两个更新的函数inet_pton和inet_ntop这2个函数能够处理ipv4和ipv6,原型如下
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);

这个函数转换字符串到网络地址,第一个参数af是地址族,转换后存在dst中
inet_pton 是inet_addr的扩展,支持的多地址族有下列:

AF_INET
src为指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函数将该地址
转换为in_addr的结构体,并复制在*dst中

AF_INET6
src为指向IPV6的地址,,函数将该地址
转换为in6_addr的结构体,并复制在*dst中
如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0。
函数inet_ntop进行相反的转换原型如下
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
这个函数转换网络二进制结构到ASCII类型的地址,参数的作用和上面相同,只是多了一个参数socklen_t cnt,他是所指向缓存区dst的大小,避免溢出,如果缓存区太小无法存储地址的值,则返回一个空指针,并将errno置为ENOSPC

网络字节顺序字节序转换

【中文标题】网络字节顺序字节序转换【英文标题】:Network byte order endianness conversion 【发布时间】:2022-01-22 11:02:35 【问题描述】:

我有以下几点:

#define IPADDR "\xc0\x80\x10\x0a" /* 192.168.1.10 */
#define PORT "\x7a\x69" /* 31337 */

但是,我终其一生都无法弄清楚十六进制值如何等于 ASCII 值。如何将其更改为不同的 IP 或端口号?

基本上我如何从IP到\xc0\x80\x10\x0a,反之亦然?

简而言之,我正在查看http://shell-storm.org/shellcode/files/shellcode-857.php,并想知道他们是如何到达那个长字符串的

谢谢

【问题讨论】:

长字符串只是上面反汇编列表中的机器码。那个以48 31 c0 开头并以0f 05 结尾。字符串也是如此。 无论你使用什么字节顺序或字节序,第一个字符串都无法解码为注释地址。其中至少有一个是错误的。 168 = 0xa8,这不在您的地址中,甚至没有反转。 【参考方案1】:

这与到达那里无关,只是表示同一事物的不同方式:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define IPADDR "\xc0\x80\x10\x0a" /* not 192.168.1.10  */
                                  /* but 192.128.16.10 */

#define PORT "\x7a\x69"           /* not 31337 */
                                  /* but 27002 */

#define c2ui(a) ((unsigned int)(unsigned char)a)

int main()

    printf("\n%u.%u.%u.%u\n", c2ui(IPADDR[0]),
                              c2ui(IPADDR[1]),
                              c2ui(IPADDR[2]),
                              c2ui(IPADDR[3]));

    printf("\n\\x%02x\\x%02x\\x%02x\\x%02x\n", c2ui(IPADDR[0]),
                                               c2ui(IPADDR[1]),
                                               c2ui(IPADDR[2]),
                                               c2ui(IPADDR[3]));
    union
    
        uint8_t s_port[3];
        uint16_t v_port;
     v;
    memcpy(v.s_port, (uint8_t *)&PORT[0], sizeof(PORT));
    printf("\nport: %u\n", v.v_port);

除了我在示例代码中指出的描述中存在错误之外。相反,在 PORT 的情况下存在问题,因为该数字是否正确取决于该程序将在其上运行的系统类型。例如,在我的系统上,要获得描述中的值,我必须反转这两个字符。出于这个原因,将这种类型的格式用于值并不是一个好主意。如果是这样写就更好了:

#define PORT 31337                /* 31337 */

【讨论】:

"\x7a\x69" 是端口 31337。端口 27002 是 "\x69\x7a" @Chris Dodd:操作...我已经将它从原来的倒过来做一个测试。现在我更正它【参考方案2】:

有标准函数 nthos/htons/ntohl/htonl 在网络和主机字节顺序之间转换 16 位和 32 位值(基本上是端口号和 ipv4 地址)。比如:

sockaddr_in  addr;

addr.sin_addr = htonl(INADDR_LOOPBACK);  // loopback address converted to network order
addr.sin_port = htons(31337);  // convert port to network order

【讨论】:

以上是关于怎么将字符串进行网络字节序转换 示例的主要内容,如果未能解决你的问题,请参考以下文章

c# 主机和网络字节序的转换 关于网络字节序和主机字节序的转换

网络字节序与主机字节序的转换

网络字节序与主机字节序的转换

主机字节序和网络字节序

请问 网络编程里的主机字节顺序和网路字节概念?

C/C++ 网络编程字节序的问题