Linux C语言 取得MTU (最大传输单元)
参照这篇博客: http://www.geekpage.jp/programming/linux-network/book/04/4-21.php
* 查看主机当前网卡,哪块在使用.
ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 options=3<RXCSUM,TXCSUM> inet6 ::1 prefixlen 128 inet 127.0.0.1 netmask 0xff000000 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 nd6 options=1<PERFORMNUD> gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280 stf0: flags=0<> mtu 1280 en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 ether a4:5e:60:d6:57:17 inet6 fe80::a65e:60ff:fed6:5717%en0 prefixlen 64 scopeid 0x4 inet 192.168.16.103 netmask 0xffffff00 broadcast 192.168.16.255 nd6 options=1<PERFORMNUD> media: autoselect status: active en1: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500 options=60<TSO4,TSO6> ether 4a:00:01:33:73:10 media: autoselect <full-duplex> status: inactive en2: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500 options=60<TSO4,TSO6> ether 4a:00:01:33:73:11 media: autoselect <full-duplex> status: inactive p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304 ether 06:5e:60:d6:57:17 media: autoselect status: inactive awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484 ether 7a:00:b6:6c:ea:a0 inet6 fe80::7800:b6ff:fe6c:eaa0%awdl0 prefixlen 64 scopeid 0x8 nd6 options=1<PERFORMNUD> media: autoselect status: active bridge0: flags=8822<BROADCAST,SMART,SIMPLEX,MULTICAST> mtu 1500 options=63<RXCSUM,TXCSUM,TSO4,TSO6> ether a6:5e:60:6d:62:00 Configuration: id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0 maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200 root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0 ipfilter disabled flags 0x2 member: en1 flags=3<LEARNING,DISCOVER> ifmaxaddr 0 port 5 priority 0 path cost 0 member: en2 flags=3<LEARNING,DISCOVER> ifmaxaddr 0 port 6 priority 0 path cost 0 media: <unknown type> status: inactive
ifconfig en0
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 ether a4:5e:60:d6:57:17 inet6 fe80::a65e:60ff:fed6:5717%en0 prefixlen 64 scopeid 0x4 inet 192.168.16.103 netmask 0xffffff00 broadcast 192.168.16.255 nd6 options=1<PERFORMNUD> media: autoselect status: active
可以看到en0网卡有有效的ip地址net 192.168.16.103, 说明这块网卡在使用, Linux环境通常是eth0.
* 创建文件main.c
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <net/if.h> int main(int argc, const char * argv[]) { int fd; struct ifreq ifr; fd = socket(AF_INET, SOCK_DGRAM, 0); strncpy(ifr.ifr_name, "en0", IFNAMSIZ-1); // eth0 if (ioctl(fd, SIOCGIFMTU, &ifr)) { perror("ioctl"); return 1; } close(fd); printf("%d\n", ifr.ifr_mtu); return 0; }
* 编译运行
1500
Program ended with exit code: 0
得出MTU为1500
* 一些函数原型
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
socket.h
/*
* Types
*/
#define SOCK_STREAM 1 /* stream socket */
#define SOCK_DGRAM 2 /* datagram socket */
#define SOCK_RAW 3 /* raw-protocol interface */
// ...
/*
* [XSI] Structure used by kernel to store most addresses.
*/
struct sockaddr {
__uint8_t sa_len; /* total length */
sa_family_t sa_family; /* [XSI] address family */
char sa_data[14]; /* [XSI] addr value (actually larger) */
};
int accept(int, struct sockaddr * __restrict, socklen_t * __restrict)
__DARWIN_ALIAS_C(accept);
int bind(int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS(bind);
int connect(int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS_C(connect);
////////////////////////////////////////////////////////////////
if.h
////////////////////////////////////////////////////////////////
/*
* Interface request structure used for socket
* ioctl's. All interface ioctl's must have parameter
* definitions which begin with ifr_name. The
* remainder may be interface specific.
*/
struct ifreq {
#ifndef IFNAMSIZ
#define IFNAMSIZ IF_NAMESIZE
#endif
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
short ifru_flags;
int ifru_metric;
int ifru_mtu;
int ifru_phys;
int ifru_media;
int ifru_intval;
caddr_t ifru_data;
struct ifdevmtu ifru_devmtu;
struct ifkpi ifru_kpi;
u_int32_t ifru_wake_flags;
u_int32_t ifru_route_refcnt;
int ifru_cap[2];
} ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
/////////////////////////////////////////////////
ioctl -- control device
SYNOPSIS
#include <sys/ioctl.h>
int ioctl(int fildes, unsigned long request, ...);