리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 비활성화하기
- 프로그래밍/리눅스 프로그래밍
- 2020. 2. 16.
반응형
본 글에서는 리눅스 시스템의 네트워크 인터페이스를 C 언어로 작성된 프로그램 상에서 비활성화하는 방법을 설명한다.
반대로, 활성화하는 방법은 다음 글에 설명되어 있다.
리눅스 시스템에서 네트워크 인터페이스를 비활성화하기 위해 보통 ifconfig down 명령을 사용한다.
아래 내용은 ifconfig eth0 down 명령을 이용하여 eth0 라는 이름을 갖는 네트워크 인터페이스를 비활성화 하는 내용이다.
root@10a25d934dda:/workspace# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:32 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2696 (2.6 KB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@10a25d934dda:/workspace#
root@10a25d934dda:/workspace# ifconfig eth0 down
root@10a25d934dda:/workspace#
root@10a25d934dda:/workspace# ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@10a25d934dda:/workspace#
C 언어로 작성된 프로그램 상에서 네트워크 인터페이스를 비활성화하는 절차는 다음과 같다.
- socket() 함수로 네트워크 인터페이스에 대한 소켓 파일 디스크립터를 연다.
- struct ifreq 구조체 변수에 활성화할 네트워크 인터페이스의 이름(예: eth0)을 저장한다.
- ioctl() 함수의 SIOCGIFFLAGS 명령을 통해 네트워크 인터페이스의 현재 상태를 가져온다.
- struct ifreq 구조체 변수의 플래그 상태 변수(ifr_flags)에 활성화 플래그를 해제한다.
- ioctl() 함수의 SIOCSIFFLAGS 명령을 통해 네트워크 인터페이스의 상태를 변경한다.
다음은 네트워크 인터페이스를 비활성화하는 예제 프로그램의 소스 코드이다.
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <stdio.h>
#include <string.h>
/**
* 네트워크 인터페이스를 비활성화한다(이는 "ifconfig down" 명령과 같은 동작이다)
*
* @param[in] ifname 비활성화하고자 하는 네트워크 인터페이스 이름
*
* @retval 0: 성공
* @retval -1: 실패
*/
int DeactivateNetworkInterface(const char *ifname)
{
printf("Deactivate network interface(%s)\n", ifname);
/*
* 네트워크 인터페이스 소켓을 연다.
*/
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
printf("Fail to deactivate network interface(%s) - socket() failed - %m\n", ifname);
return -1;
}
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
/*
* 네트워크 인터페이스의 현재 상태를 읽어온다.
*/
int ret = ioctl(sockfd, SIOCGIFFLAGS, &ifr);
if (ret < 0) {
printf("Fail to deactivate network interface(%s) - ioctl(SIOCGIFFLAGS) failed - %m\n", ifname);
return -1;
}
/*
* 인터페이스를 비활성화 상태로 설정한다.
*/
ifr.ifr_flags &= ~IFF_UP;
ret = ioctl(sockfd, SIOCSIFFLAGS, &ifr);
if (ret < 0) {
printf("Fail to deactivate network interface(%s) - ioctl(SIOCSIFFLAGS) failed - %m\n", ifname);
return -1;
}
printf("Success to deactivate network interface\n");
return 0;
}
/**
* 테스트 어플리케이션
*/
int main(int argc, char *argv[])
{
const char *ifname = "eth0";
/*
* "eth0" 네트워크 인터페이스를 비활성화한다.
*/
return DeactivateNetworkInterface(ifname);
}
위 코드를 빌드 후, eth0 인터페이스가 활성화된 상태에서 실행하면 해당 인터페이스가 비활성화 되는 것을 확인할 수 있다.
참고로 위 프로그램은 네트워크 디바이스에 접근하므로 관리자 권한으로 실행되어야 한다.
예를 들어, 도커 컨테이너는 privileged 모드로 실행되어야 한다.
root@10a25d934dda:/workspace# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:37 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3126 (3.1 KB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@10a25d934dda:/workspace#
root@10a25d934dda:/workspace# ./deactivate
Deactivate network interface(eth0)
Success to deactivate network interface
root@10a25d934dda:/workspace#
root@10a25d934dda:/workspace# ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@10a25d934dda:/workspace#
파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음
'프로그래밍 > 리눅스 프로그래밍' 카테고리의 다른 글
리눅스 프로그래밍 - 프로세스 종료 신호(SIGINT, SIGTERM) 후킹하기 (0) | 2020.08.21 |
---|---|
리눅스 타이머 프로그래밍 (0) | 2020.07.31 |
리눅스 네트워크 프로그래밍 - CAN(Controller Area Network) 통신 (2) | 2020.04.27 |
리눅스 네트워크 프로그래밍 - UDP6(UDP over IPv6) 송수신 (0) | 2020.03.04 |
리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 활성화하기 (0) | 2020.02.15 |
리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 MAC 주소 확인하기 (0) | 2020.02.15 |
리눅스 네트워크 프로그래밍 - 네트워크 인터페이스 MAC 주소 설정하기 (0) | 2020.02.15 |
리눅스 네트워크 프로그래밍 - inet_ntop() : IPv6 주소를 문자열로 변환 (0) | 2020.02.12 |