Linux下C语言操作网卡的几个代码实例!特别实用(几个.网卡.实例.语言.特别...........)

wufei123 2025-01-05 阅读:35 评论:0
下面是对原文的重新表述,重点在于如何用c语言直接操作网络接口,例如读写ip地址和mac地址。 如何使用C语言直接操作网络接口? 在这篇文章中,我们将讨论如何在C语言中直接操作网络接口。这包括读取和修改IP地址、MAC地址等信息。 1. 基本...

下面是对原文的重新表述,重点在于如何用c语言直接操作网络接口,例如读写ip地址和mac地址。

如何使用C语言直接操作网络接口?

在这篇文章中,我们将讨论如何在C语言中直接操作网络接口。这包括读取和修改IP地址、MAC地址等信息。

1. 基本原理

我们可以通过使用系统提供的socket()和ioctl()函数来实现这些操作。这些函数允许我们与网络接口进行直接的交互,从而获取和设置与网络有关的各种参数。

你可以通过使用这些C语言函数来控制和管理当前系统上的网络接口。通过这两种系统调用,我们可以轻松实现网络接口的操作和管理。

JavaScript
int socket(int domain, int type, int protocol);
功能:
    创建套接字
参数:
 domain: 
  Name                Purpose                          Man page
  AF_UNIX, AF_LOCAL   Local communication              unix(7)
  AF_INET             IPv4 Internet protocols          ip(7)

 type:
  SOCK_STREAM     Provides sequenced, reliable, two-way, connection-based
                      byte  streams.  An out-of-band data transmission mecha‐
                      nism may be supported.
      SOCK_DGRAM      Supports datagrams (connectionless, unreliable messages
                      of a fixed maximum length).
 protocol:
  通常为0
返回值:
 成功:新的套接字的文件描述符
 失败:错误码,负值
int ioctl(int fd, unsigned long request, ...);
参数:
   fd :文件描述符
   request:命令
   ... :参数

其中网络用到的request定义头文件位于:

JavaScript
/usr/include/linux/sockios.h
/* Linux-specific socket ioctls */
#define SIOCINQ  FIONREAD
#define SIOCOUTQ TIOCOUTQ        /* output queue size (not sent + not acked) */

/* Routing table calls. */
#define SIOCADDRT 0x890B  /* add routing table entry */
#define SIOCDELRT 0x890C  /* delete routing table entry */
#define SIOCRTMSG 0x890D  /* call to routing system */

/* Socket configuration controls. */
#define SIOCGIFNAME 0x8910  /* get iface name  */
#define SIOCSIFLINK 0x8911  /* set iface channel  */
#define SIOCGIFCONF 0x8912  /* get iface list  */
#define SIOCGIFFLAGS 0x8913  /* get flags   */
#define SIOCSIFFLAGS 0x8914  /* set flags   */
#define SIOCGIFADDR 0x8915  /* get PA address  */
#define SIOCSIFADDR 0x8916  /* set PA address  */
#define SIOCGIFDSTADDR 0x8917  /* get remote PA address */
#define SIOCSIFDSTADDR 0x8918  /* set remote PA address */
#define SIOCGIFBRDADDR 0x8919  /* get broadcast PA address */
#define SIOCSIFBRDADDR 0x891a  /* set broadcast PA address */
#define SIOCGIFNETMASK 0x891b  /* get network PA mask  */
#define SIOCSIFNETMASK 0x891c  /* set network PA mask  */
#define SIOCGIFMETRIC 0x891d  /* get metric   */
#define SIOCSIFMETRIC 0x891e  /* set metric   */
#define SIOCGIFMEM 0x891f  /* get memory address (BSD) */
#define SIOCSIFMEM 0x8920  /* set memory address (BSD) */
#define SIOCGIFMTU 0x8921  /* get MTU size   */
#define SIOCSIFMTU 0x8922  /* set MTU size   */
#define SIOCSIFNAME 0x8923  /* set interface name */
#define SIOCSIFHWADDR 0x8924  /* set hardware address  */
#define SIOCGIFENCAP 0x8925  /* get/set encapsulations       */
#define SIOCSIFENCAP 0x8926  
#define SIOCGIFHWADDR 0x8927  /* Get hardware address  */
#define SIOCGIFSLAVE 0x8929  /* Driver slaving support */
#define SIOCSIFSLAVE 0x8930
#define SIOCADDMULTI 0x8931  /* Multicast address lists */
#define SIOCDELMULTI 0x8932
#define SIOCGIFINDEX 0x8933  /* name -> if_index mapping */
#define SIOGIFINDEX SIOCGIFINDEX /* misprint compatibility :-) */
#define SIOCSIFPFLAGS 0x8934  /* set/get extended flags set */
#define SIOCGIFPFLAGS 0x8935
#define SIOCDIFADDR 0x8936  /* delete PA address  */
#define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */
#define SIOCGIFCOUNT 0x8938  /* get number of devices */
……

其中ioctl的参数需要借助结构体struct ifreq, 定义头文件:

JavaScript
/usr/include/linux/if.h
#if __UAPI_DEF_IF_IFREQ
struct ifreq {
#define IFHWADDRLEN 6
 union
 {
  char ifrn_name[IFNAMSIZ];  /* if name, e.g. "en0" */
 } ifr_ifrn;
 
 union {
  struct sockaddr ifru_addr;
  struct sockaddr ifru_dstaddr;
  struct sockaddr ifru_broadaddr;
  struct sockaddr ifru_netmask;
  struct  sockaddr ifru_hwaddr;
  short ifru_flags;
  int ifru_ivalue;
  int ifru_mtu;
  struct  ifmap ifru_map;
  char ifru_slave[IFNAMSIZ]; /* Just fits the size */
  char ifru_newname[IFNAMSIZ];
  void * ifru_data;
  struct if_settings ifru_settings;
 } ifr_ifru;
};
#endif /* __UAPI_DEF_IF_IFREQ */

#define ifr_name ifr_ifrn.ifrn_name /* interface name  */
#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address   */
#define ifr_addr ifr_ifru.ifru_addr /* address  */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
#define ifr_flags ifr_ifru.ifru_flags /* flags  */
#define ifr_metric ifr_ifru.ifru_ivalue /* metric  */
#define ifr_mtu  ifr_ifru.ifru_mtu /* mtu   */
#define ifr_map  ifr_ifru.ifru_map /* device map  */
#define ifr_slave ifr_ifru.ifru_slave /* slave device  */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
#define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
#define ifr_bandwidth ifr_ifru.ifru_ivalue    /* link bandwidth */
#define ifr_qlen ifr_ifru.ifru_ivalue /* Queue length  */
#define ifr_newname ifr_ifru.ifru_newname /* New name  */
#define ifr_settings ifr_ifru.ifru_settings /* Device/proto settings*/

二、函数实现

下面将实现不同功能的函数一一列举。

1. 获取本机网卡IP
JavaScript
int getLocalIp(const char *eth, char *ip) {
    struct ifreq ifr;
    struct sockaddr_in sin;
    int fd;
    bzero(&ifr, sizeof(ifr));
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) return -1;
    }
    strcpy(ifr.ifr_name, eth);
    if (ioctl(fd, SIOCGIFADDR, &ifr) return -1;
    }
    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));
    close(fd);
    return 0;
}

2. 设置本网卡IP地址
JavaScript
int setIpAddrManual(const char *eth, char *ipstr) {
    int fd;
    struct sockaddr_in sin;
    struct ifreq ifr;
    bzero(&ifr, sizeof(ifr));
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) return -1;
    }
    strcpy(ifr.ifr_name, eth);

 sin.sin_addr.s_addr = inet_addr(ipstr);
 
 sin.sin_family = AF_INET;
    memcpy(&ifr.ifr_addr, &sin, sizeof(sin));
 
    if (ioctl(fd, SIOCSIFADDR, &ifr) "");
        close(fd);
        return -1;
    }
    close(fd);
    return 0;
} 

3. 获取本机网卡Mac地址
JavaScript
int getLocalMac(const char *eth, char *mac) {


    int fd;
    struct ifreq ifr;
    bzero(&ifr, sizeof(ifr));
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) return -1;
    }
    strcpy(ifr.ifr_name, eth);
    if (ioctl(fd, SIOCGIFHWADDR, &ifr) return -1;
    }
   snprintf(mac,18, "%02x:%02x:%02x:%02x:%02x:%02x",
         (unsigned char) ifr.ifr_hwaddr.sa_data[0],
         (unsigned char) ifr.ifr_hwaddr.sa_data[1],
         (unsigned char) ifr.ifr_hwaddr.sa_data[2],
         (unsigned char) ifr.ifr_hwaddr.sa_data[3],
         (unsigned char) ifr.ifr_hwaddr.sa_data[4],
         (unsigned char) ifr.ifr_hwaddr.sa_data[5]);
    close(fd);
    return 0;

} 

4. 设置网卡mac地址
JavaScript
/*
support format [00:11:22:33:44:55]
*/
#define MAC_ARRAY(mac_array)  (unsigned int *)&mac_array[0],(unsigned int *)&mac_array[1],(unsigned int *)&mac_array[2],(unsigned int *)&mac_array[3],(unsigned int *)&mac_array[4],(unsigned int *)&mac_array[5] 
int setLocalMac(const char *eth, char *mac) {
    int fd;
    struct ifreq ifr;
 unsigned char mac_array[6] = {0};
 
    bzero(&ifr, sizeof(ifr));
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) return -1;
    }
    strcpy(ifr.ifr_name, eth);
 ifr.ifr_hwaddr.sa_family = AF_LOCAL;
 
 sscanf(mac,"%02x:%02x:%02x:%02x:%02x:%02x",
  MAC_ARRAY(mac_array));

 memcpy(ifr.ifr_hwaddr.sa_data,mac_array,6);

    if (ioctl(fd, SIOCSIFHWADDR, &ifr) "SIOCSIFHWADDR:");
        close(fd);
        return -1;
    }

    close(fd);
    return 0;
} 

注意:

  • 网卡地址的第一字节必须是偶数
  • sa_family 值必须为:AF_LOCAL

5. 获取网卡mtu
JavaScript
int getMtu(const char *eth, char *mtu) {
    int fd;
    struct ifreq ifr;
    bzero(&ifr, sizeof(ifr));
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) return -1;
    }
    strcpy(ifr.ifr_name, eth);
    if (ioctl(fd, SIOCGIFMTU, &ifr) return -1;
    } 
    snprintf(mtu,64, "%d", (unsigned char) ifr.ifr_mtu);
    close(fd);
    return 0;
} 

6. 获取广播地址
JavaScript
int getBroadAddr(const char *eth, char *ip) {
    int fd;
    struct sockaddr_in sin;
    struct ifreq ifr;
    bzero(&ifr, sizeof(ifr));
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) return -1;
    }
    strcpy(ifr.ifr_name, eth);
    if (ioctl(fd, SIOCGIFBRDADDR, &ifr) "");
        close(fd);
        return -1;
    }
    memcpy(&sin, &ifr.ifr_broadaddr, sizeof(sin));
    snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));

    close(fd);
    return 0;
} 

7. 获取掩码
JavaScript
int getNetMask(const char *eth, char *mask) {
    int fd;
    struct sockaddr_in sin;
    struct ifreq ifr;
    bzero(&ifr, sizeof(ifr));
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) return -1;
    }
    strcpy(ifr.ifr_name, eth);
    if (ioctl(fd, SIOCGIFNETMASK, &ifr) "");
        close(fd);
        return -1;
    }
    memcpy(&sin, &ifr.ifr_netmask, sizeof(sin));
    snprintf(mask, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));

    close(fd);
    return 0;
}

8. 获取网卡flag
JavaScript
int getFlags(const char *eth, char *fg) {
    int fd;
    struct sockaddr_in sin;
    struct ifreq ifr;
    bzero(&ifr, sizeof(ifr));
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) return -1;
    }
    strcpy(ifr.ifr_name, eth);
    if (ioctl(fd, SIOCGIFFLAGS, &ifr) "");
        close(fd);
        return -1;
    }
 snprintf(fg, IP_SIZE, "%x", ifr.ifr_flags);

    close(fd);
    return 0;
} 

三、测试

1. 测试程序
JavaScript
int main(int argc, char **argv)
{
 int fg=0;
 char mac[32]={};
 char ip[IP_SIZE]={0};
 char buf[64];


 getBroadAddr(ethname,ip);
 printf("broad ip:	%s
",ip);

 getNetMask(ethname,ip);
 printf("mask:	%s
",ip);
 
 setIpAddrManual(ethname, "1.1.1.1");
 getLocalIp(ethname,ip);
 printf("ip:	%s
",ip);
 
 setLocalMac(ethname,"00:11:22:33:44:55");
 getLocalMac(ethname,mac);
 printf("mac:	%s
",mac);

 getMtu(ethname,buf);
 printf("mtu:	%s
",buf); 

 return 1;
}

2. 执行结果 Linux下C语言操作网卡的几个代码实例!特别实用

执行后结果:

JavaScript
peng@ubuntu:~/work/test/ip$ ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:11:22:33:44:55  
          inet addr:1.1.1.1  Bcast:1.255.255.255  Mask:255.0.0.0
          inet6 addr: fe80::d9d4:d42b:a04a:9d40/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:188577 errors:0 dropped:0 overruns:0 frame:0
          TX packets:208116 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:53762370 (53.7 MB)  TX bytes:172094089 (172.0 MB)

完整代码,后天回复:eth

以上就是Linux下C语言操作网卡的几个代码实例!特别实用的详细内容,更多请关注知识资源分享宝库其它相关文章!

版权声明

本站内容来源于互联网搬运,
仅限用于小范围内传播学习,请在下载后24小时内删除,
如果有侵权内容、不妥之处,请第一时间联系我们删除。敬请谅解!
E-mail:dpw1001@163.com

分享:

扫一扫在手机阅读、分享本文

发表评论
热门文章
  • BioWare埃德蒙顿工作室面临关闭危机,龙腾世纪制作总监辞职引关注(龙腾.总监.辞职.危机.面临.....)

    BioWare埃德蒙顿工作室面临关闭危机,龙腾世纪制作总监辞职引关注(龙腾.总监.辞职.危机.面临.....)
    知名变性人制作总监corrine busche离职bioware,引发业界震荡!外媒“smash jt”独家报道称,《龙腾世纪:影幢守护者》制作总监corrine busche已离开bioware,此举不仅引发了关于个人职业发展方向的讨论,更因其可能预示着bioware埃德蒙顿工作室即将关闭而备受关注。本文将深入分析busche离职的原因及其对bioware及游戏行业的影响。 Busche的告别信:挑战与感激并存 据“Smash JT”获得的内部邮件显示,Busche离职原...
  • 闪耀暖暖靡城永恒怎么样-闪耀暖暖靡城永恒套装介绍(闪耀.暖暖.套装.介绍.....)

    闪耀暖暖靡城永恒怎么样-闪耀暖暖靡城永恒套装介绍(闪耀.暖暖.套装.介绍.....)
    闪耀暖暖钻石竞技场第十七赛季“华梦泡影”即将开启!全新闪耀性感套装【靡城永恒】震撼来袭!想知道如何获得这套精美套装吗?快来看看吧! 【靡城永恒】套装设计理念抢先看: 设计灵感源于夜色中的孤星,象征着淡然、漠视一切的灰色瞳眸。设计师希望通过这套服装,展现出在虚幻与真实交织的夜幕下,一种独特的魅力。 服装细节考究,从面料的光泽、鞋跟声响到裙摆的弧度,都力求完美还原设计初衷。 【靡城永恒】套装设计亮点: 闪耀的绸缎与金丝交织,轻盈的羽毛增添华贵感。 这套服装仿佛是从无尽的黑...
  • python怎么调用其他文件函数

    python怎么调用其他文件函数
    在 python 中调用其他文件中的函数,有两种方式:1. 使用 import 语句导入模块,然后调用 [模块名].[函数名]();2. 使用 from ... import 语句从模块导入特定函数,然后调用 [函数名]()。 如何在 Python 中调用其他文件中的函数 在 Python 中,您可以通过以下两种方式调用其他文件中的函数: 1. 使用 import 语句 优点:简单且易于使用。 缺点:会将整个模块导入到当前作用域中,可能会导致命名空间混乱。 步骤:...
  • 斗魔骑士哪个角色强势-斗魔骑士角色推荐与实力解析(骑士.角色.强势.解析.实力.....)

    斗魔骑士哪个角色强势-斗魔骑士角色推荐与实力解析(骑士.角色.强势.解析.实力.....)
    斗魔骑士角色选择及战斗策略指南 斗魔骑士游戏中,众多角色各具特色,选择适合自己的角色才能在战斗中占据优势。本文将为您详细解读如何选择强力角色,并提供团队协作及角色培养策略。 如何选择强力角色? 斗魔骑士的角色大致分为近战和远程两种类型。近战角色通常拥有高攻击力和防御力,适合冲锋陷阵;远程角色则擅长后方输出,并依靠灵活走位躲避攻击。 选择角色时,需根据个人游戏风格和喜好决定。喜欢正面硬刚的玩家可以选择战士型角色,其高生命值和防御力能承受更多伤害;偏好策略性玩法的玩家则可以选择法...
  • 奇迹暖暖诸星梦眠怎么样-奇迹暖暖诸星梦眠套装介绍(星梦.暖暖.奇迹.套装.介绍.....)

    奇迹暖暖诸星梦眠怎么样-奇迹暖暖诸星梦眠套装介绍(星梦.暖暖.奇迹.套装.介绍.....)
    奇迹暖暖全新活动“失序之圜”即将开启,参与活动即可获得精美套装——诸星梦眠!想知道这套套装的细节吗?一起来看看吧! 奇迹暖暖诸星梦眠套装详解 “失序之圜”活动主打套装——诸星梦眠,高清海报震撼公开!少女在无垠梦境中,接受星辰的邀请,馥郁芬芳,预示着命运之花即将绽放。 诸星梦眠套装包含:全新妆容“隽永之梦”、星光面饰“熠烁星光”、动态特姿连衣裙“诸星梦眠”、动态特姿发型“金色绮想”、精美特效皇冠“繁星加冕”,以及动态摆件“芳馨酣眠”、“沉云余音”、“流星低语”、“葳蕤诗篇”。...