Reputation: 65
At the moment my program is making a system()
call to ifconfig
to do this.
It seems a bit messy - maybe ifconfig
is not on the path, or in some non-standard location. And then I'd need to check for the iproute2 equivalent in case of failure.
Is there a way to set this programmatically using C?
Upvotes: 4
Views: 4916
Reputation: 5055
You can also use netlink. The full example:
#include <stdio.h>
#include <string.h>
#include <net/if.h>
#include <sys/socket.h>
#include <linux/rtnetlink.h>
#define IFACE_NAME "enp5s0"
int main(void) {
int ret, nl_sock;
unsigned int mtu = 8000;
struct rtattr *rta;
struct {
struct nlmsghdr nh;
struct ifinfomsg ifinfo;
char attrbuf[512];
} req;
nl_sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
if(nl_sock < 0) {
perror("socket():");
return -1;
}
memset(&req, 0, sizeof req);
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
req.nh.nlmsg_flags = NLM_F_REQUEST;
req.nh.nlmsg_type = RTM_NEWLINK; // RTM_SETLINK
req.ifinfo.ifi_family = AF_UNSPEC;
req.ifinfo.ifi_index = if_nametoindex(IFACE_NAME);
if(!req.ifinfo.ifi_index) {
perror("if_nametoindex():");
return -1;
}
printf("%s index: %d\n", IFACE_NAME, req.ifinfo.ifi_index);
req.ifinfo.ifi_change = 0xffffffff;
rta = (struct rtattr *)(((char *) &req) + NLMSG_ALIGN(req.nh.nlmsg_len));
rta->rta_type = IFLA_MTU;
rta->rta_len = RTA_LENGTH(sizeof(unsigned int));
req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + RTA_LENGTH(sizeof mtu);
memcpy(RTA_DATA(rta), &mtu, sizeof mtu);
ret = send(nl_sock, &req, req.nh.nlmsg_len, 0);
if(ret < 0) {
perror("send():");
return -1;
}
return 0;
}
Also read: rtnetlink(3), rtnetlink(7)
Upvotes: 5
Reputation: 6674
You can set the SIOCSIFMTU field in an ioctl call, something like this:
struct ifreq ifr;
ifr.ifr_addr.sa_family = AF_INET;//address family
strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));//interface name where you want to set the MTU
ifr.ifr_mtu = 9100; //your MTU size here
if (ioctl(sockfd, SIOCSIFMTU, (caddr_t)&ifr) < 0)
//failed to set MTU. handle error.
The above code will set the MTU of a device(as in ifr.name) using ifr_mtu field in the ifreq structure.
Refer: http://linux.die.net/man/7/netdevice
Upvotes: 5