iplink.c revision aba5acdfdb347d2c21fc67d613d83d4430ca3937
1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* 2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * iplink.c "ip link". 3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * This program is free software; you can redistribute it and/or 5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * modify it under the terms of the GNU General Public License 6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * as published by the Free Software Foundation; either version 7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 2 of the License, or (at your option) any later version. 8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */ 12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h> 14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h> 15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h> 16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h> 17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h> 18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <errno.h> 19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h> 20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if.h> 21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_packet.h> 22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_ether.h> 23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/sockios.h> 24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h> 25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h> 26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h> 27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/ioctl.h> 28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/sockios.h> 29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "rt_names.h" 31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h" 32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "ip_common.h" 33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) __attribute__((noreturn)); 36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid iplink_usage(void) 38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Usage: ip link set DEVICE { up | down | arp { on | off } |\n"); 40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " dynamic { on | off } |\n"); 41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " multicast { on | off } | txqueuelen PACKETS |\n"); 42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " name NEWNAME |\n"); 43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " address LLADDR | broadcast LLADDR |\n"); 44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " mtu MTU }\n"); 45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " ip link show [ DEVICE ]\n"); 46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) 50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger iplink_usage(); 52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int on_off(char *msg) 55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Error: argument of \"%s\" must be \"on\" or \"off\"\n", msg); 57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int get_ctl_fd(void) 61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s_errno; 63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int fd; 64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = socket(PF_INET, SOCK_DGRAM, 0); 66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd >= 0) 67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return fd; 68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s_errno = errno; 69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = socket(PF_PACKET, SOCK_DGRAM, 0); 70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd >= 0) 71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return fd; 72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = socket(PF_INET6, SOCK_DGRAM, 0); 73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd >= 0) 74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return fd; 75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger errno = s_errno; 76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("Cannot create control socket"); 77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int do_chflags(char *dev, __u32 flags, __u32 mask) 81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int fd; 84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int err; 85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(ifr.ifr_name, dev); 87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = get_ctl_fd(); 88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd < 0) 89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger err = ioctl(fd, SIOCGIFFLAGS, &ifr); 91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (err) { 92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCGIFFLAGS"); 93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((ifr.ifr_flags^flags)&mask) { 97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr.ifr_flags &= ~mask; 98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr.ifr_flags |= mask&flags; 99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger err = ioctl(fd, SIOCSIFFLAGS, &ifr); 100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (err) 101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFFLAGS"); 102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return err; 105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int do_changename(char *dev, char *newdev) 108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int fd; 111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int err; 112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(ifr.ifr_name, dev); 114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(ifr.ifr_newname, newdev); 115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = get_ctl_fd(); 116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd < 0) 117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger err = ioctl(fd, SIOCSIFNAME, &ifr); 119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (err) { 120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFNAME"); 121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return err; 126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int set_qlen(char *dev, int qlen) 129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = get_ctl_fd(); 134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) 135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(ifr.ifr_name, dev); 139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr.ifr_qlen = qlen; 140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) { 141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFXQLEN"); 142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int set_mtu(char *dev, int mtu) 151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = get_ctl_fd(); 156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) 157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(ifr.ifr_name, dev); 161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr.ifr_mtu = mtu; 162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { 163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFMTU"); 164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int get_address(char *dev, int *htype) 173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_ll me; 176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int alen; 177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = socket(PF_PACKET, SOCK_DGRAM, 0); 180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) { 181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("socket(PF_PACKET)"); 182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 185aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 186aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(ifr.ifr_name, dev); 187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { 188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCGIFINDEX"); 189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&me, 0, sizeof(me)); 194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger me.sll_family = AF_PACKET; 195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger me.sll_ifindex = ifr.ifr_ifindex; 196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger me.sll_protocol = htons(ETH_P_LOOP); 197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { 198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("bind"); 199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger alen = sizeof(me); 204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { 205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("getsockname"); 206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 209aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *htype = me.sll_hatype; 211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return me.sll_halen; 212aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr) 215aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int alen; 217aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 218aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(ifr, 0, sizeof(*ifr)); 219aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(ifr->ifr_name, dev); 220aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr->ifr_hwaddr.sa_family = hatype; 221aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla); 222aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (alen < 0) 223aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 224aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (alen != halen) { 225aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Wrong address (%s) length: expected %d bytes\n", lla, halen); 226aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 227aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 228aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 229aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 230aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 231aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int set_address(struct ifreq *ifr, int brd) 232aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 233aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 234aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 235aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = get_ctl_fd(); 236aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) 237aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 238aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, brd?SIOCSIFHWBROADCAST:SIOCSIFHWADDR, ifr) < 0) { 239aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror(brd?"SIOCSIFHWBROADCAST":"SIOCSIFHWADDR"); 240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 243aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 245aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 248aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int do_set(int argc, char **argv) 249aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *dev = NULL; 251aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 mask = 0; 252aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 flags = 0; 253aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int qlen = -1; 254aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int mtu = -1; 255aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *newaddr = NULL; 256aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *newbrd = NULL; 257aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr0, ifr1; 258aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *newname = NULL; 259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int htype, halen; 260aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 262aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "up") == 0) { 263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_UP; 264aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_UP; 265aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "down") == 0) { 266aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_UP; 267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_UP; 268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "name") == 0) { 269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 270aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger newname = *argv; 271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "address") == 0) { 272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger newaddr = *argv; 274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "broadcast") == 0 || 275aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "brd") == 0) { 276aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 277aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger newbrd = *argv; 278aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "txqueuelen") == 0 || 279aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "qlen") == 0 || 280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "txqlen") == 0) { 281aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 282aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (qlen != -1) 283aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("txqueuelen", *argv); 284aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_integer(&qlen, *argv, 0)) 285aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg("Invalid \"txqueuelen\" value\n", *argv); 286aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "mtu") == 0) { 287aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 288aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (mtu != -1) 289aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("mtu", *argv); 290aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_integer(&mtu, *argv, 0)) 291aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg("Invalid \"mtu\" value\n", *argv); 292aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "multicast") == 0) { 293aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_MULTICAST; 295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "on") == 0) { 296aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_MULTICAST; 297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "off") == 0) { 298aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_MULTICAST; 299aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 300aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return on_off("multicast"); 301aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "arp") == 0) { 302aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 303aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_NOARP; 304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "on") == 0) { 305aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_NOARP; 306aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "off") == 0) { 307aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_NOARP; 308aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return on_off("noarp"); 310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#ifdef IFF_DYNAMIC 311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "dynamic") == 0) { 312aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 313aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_DYNAMIC; 314aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "on") == 0) { 315aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_DYNAMIC; 316aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "off") == 0) { 317aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_DYNAMIC; 318aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 319aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return on_off("dynamic"); 320aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif 321aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 322aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "dev") == 0) { 323aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 324aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 325aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 326aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 327aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dev) 328aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg2("dev", *argv); 329aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dev = *argv; 330aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 331aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 332aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 333aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 334aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!dev) { 335aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Not enough of information: \"dev\" argument is required.\n"); 336aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 337aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 338aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 339aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr || newbrd) { 340aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger halen = get_address(dev, &htype); 341aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (halen < 0) 342aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 343aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr) { 344aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0) 345aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 346aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 347aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newbrd) { 348aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) 349aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 350aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 351aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 352aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 353aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newname && strcmp(dev, newname)) { 354aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_changename(dev, newname) < 0) 355aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 356aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dev = newname; 357aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 358aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (qlen != -1) { 359aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_qlen(dev, qlen) < 0) 360aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 361aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 362aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (mtu != -1) { 363aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_mtu(dev, mtu) < 0) 364aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 365aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 366aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr || newbrd) { 367aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newbrd) { 368aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_address(&ifr1, 1) < 0) 369aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 370aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 371aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr) { 372aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_address(&ifr0, 0) < 0) 373aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 374aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 375aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 376aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (mask) 377aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return do_chflags(dev, flags, mask); 378aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 379aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 380aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 381aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_iplink(int argc, char **argv) 382aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 383aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc > 0) { 384aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "set") == 0) 385aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return do_set(argc-1, argv+1); 386aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "show") == 0 || 387aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "lst") == 0 || 388aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "list") == 0) 389aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipaddr_list_link(argc-1, argv+1); 390aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 391aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 392aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 393aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipaddr_list_link(0, NULL); 394aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 395aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Command \"%s\" is unknown, try \"ip link help\".\n", *argv); 396aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 397aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 398