C网络通讯打印MAC地址和IP地址

    技术2025-09-22  17

    在做网络通讯开发的时候,有时候需要直接从原始数据包中分析,ip地址和mac地址,这个时候不能直接inet_XXXX()

    比如现在我要使用原始套接字,拿到数据链路曾以太网协议数据包,通过操作指针拿到IP,MAC,总结下工作中常用的打印IP 地址和MAC地址的方法 #ifndef ADDRESS_TOOL #define ADDRESS_TOOL #include<stdlib.h> #include<unistd.h> #include<stdio.h> #include<sys/socket.h> #include<netinet/in.h> #include<string.h> typedef unsigned char uint8_t; char *Mac_Print(uint8_t *Mac,char*buf,size_t len);//传入6字节 mac地址, 传出大于32字节char buf[32]=0,传入buf大小 char *IP_Print(uint8_t *Ip,char*buf,size_t len);//传入4字节 mac地址, 传出大于32字节char buf[32]=0,传入buf大小 char* inet_ntoa_v2(struct in_addr in,char*buf,size_t len);//传入struct in_addr ip地址, 传出大于32字节char buf[32]=0,传入buf大小 #endif #include "Address_Tool.h" char *Mac_Print(uint8_t *Mac,char*buf,size_t len) { if (len<31) { perror("In Function Mac_Print buf too small\n"); return (char*)0; } sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", Mac[0], Mac[1], Mac[2], Mac[3], Mac[4], Mac[5]); return buf; } char *IP_Print(uint8_t *Ip,char*buf,size_t len) { if (len<13) { perror("In Function IP_Print buf too small\n"); return (char*)0; } sprintf(buf, "%u.%u.%u.%u", Ip[0], Ip[1], Ip[2], Ip[3]); return buf; } char* inet_ntoa_v2(struct in_addr in,char*buf,size_t len) { if (len<13) { perror("In Function inet_ntoa_v2 buf too small\n"); return (char*)0; } uint8_t Ip[5]={0}; memcpy(Ip,&in.s_addr,4);//in.s_addr是 是uint32 也就是 unsigned int 32位无符号数据 //站位4字节, 此时把它转化为 uint8 方便一些,所以memcpy到刚才的数组4字节。 sprintf(buf, "%u.%u.%u.%u", Ip[0], Ip[1], Ip[2], Ip[3]); return buf; } 为什么要用unsigned char * 而不是 char * ?原因很简单 思考 char 是一字节,在计算机中8位是一个字节,也就是说 char 表示数字的话就是 最大值为 1111 1111 既 10 进制 255又因为是有符号的 那么范围就是 -128 — +128 ,显然不够ip地址使用,而unsigned char 刚刚好满足 0-255 的需求。inet_ntoa_v2()这个函数是我考虑到inet_ntoa这个函数不可重用性。所以写了这么个函数,写完我发现其实和inet_ntop()类似。
    Processed: 0.024, SQL: 10