|
|
  |
Как установить новый ip-адрес интерфейса программно? |
|
|
|
Nov 30 2014, 14:37
|
Местный
  
Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468

|
Здравствуйте! Есть задача - установить новый ip-адрес интерфейса из работающей программы. Из консоли делается просто: "ifconfig eth0 inet 192.168.1.10". Попробовал аналогично вызвать ifconfig из пользовательской программы: Код int main(int argc, char* argv[], char* enpv[]) { pid_t num; int status; num = fork(); if(num == 0) { execl("ifconfig", "eth0", "inet", "10.0.2.16"); } else { wait(&status); printf("ending"); } return 0; } Запускаю, проверяю - адрес не меняется. Что я делают не так? Запускаю эту программу под рутом. Менять адрес через перезапись в файлах конфигурации - не хочу, т.к. у разных дистрибутивов эти файлы лежат в разных папках. Заранее спасибо.
|
|
|
|
|
Nov 30 2014, 15:53
|
Профессионал
    
Группа: Свой
Сообщений: 1 700
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596

|
зависит от того, чем управляются интерфейсы в системе в принципе. у разных дистрибутивов разные подходы, поэтому придётся адаптироваться. Если в системе установлен пакет NetworkManager, то надо работать через него, вернее с ним через D-Bus. Потому как он может в любой момент изменить то что вы там наделали вручную без его ведома. Если через скрипты, то либо дорабатывать скрипты, либо убирать их совсем и делать все дела самому. в крайнем случае: https://www.kernel.org/pub/linux/utils/net/...2-3.17.0.tar.gzсмотреть исходник ip/ipaddr.c
--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
|
|
|
|
|
Nov 30 2014, 18:27
|
Знающий
   
Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245

|
смотрите как надо вызывать execl, там что то как то не все так просто т.к. при вызове main(int argc, char *argv[]) Цитата argv[0] указывает на первую символьную строку, которой всегда является имя программы; argv[1] указывает на первый аргумент и так далее. а в execl присутвует path.
|
|
|
|
|
Nov 30 2014, 19:32
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Код struct sockaddr_in sin; int s;
s = socket(AF_INET,SOCK_DGRAM,0); //temporary socket
memset(&ifr, 0, sizeof(struct ifreq)); memset(&sin, 0, sizeof(struct sockaddr)); strncpy(ifr.ifr_name, iface, IF_NAMESIZE-1); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr("192.168.0.123");
memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
if(ioctl(s, SIOCSIFADDR, &ifr)< 0){ //set IP-Adress and check for errors close(s); perror("ioctl()"); exit(1); } как-то так. Но это до первой перезагрузки, если init запускает стартовые скрипты.
|
|
|
|
|
Dec 5 2014, 15:39
|
Местный
  
Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468

|
Спасибо за ответы. Несколько дней понадобилось, чтобы разобраться с ioctl. Код - как у psL: Код s = socket(AF_INET,SOCK_DGRAM,0); //temporary socket
memset(&ifr, 0, sizeof(struct ifreq)); memset(&sin, 0, sizeof(struct sockaddr)); strncpy(ifr.ifr_name, "eth0", IF_NAMESIZE-1); sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr("192.168.0.123");
memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
if(ioctl(s, SIOCSIFADDR, &ifr)< 0) //set IP-Adress and check for errors { /*close(s);*/ } close(s); Но проблема в том, что опять ничего не работает. На машине Ubuntu все отлично работает: адрес меняется. Когда запускаю этот код в Angstrom - нифига не пашет. Вот что пишет ifconfig -a. Код eth0 Link encap:Ethernet HWaddr BC:6A:29:57:11:80 BROADCAST MULTICAST MTU:1500 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)
eth1 Link encap:Ethernet HWaddr BC:6A:29:57:11:81 BROADCAST MULTICAST MTU:1500 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) Запускаю из-под рута. Может разрешений не хватает ? Но ведь из sh - все задается.
|
|
|
|
|
Dec 5 2014, 17:21
|
Местный
  
Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468

|
Команда: Код system("ifconfig eth0 10.0.5.20"); действительно позволила установить новый ip. Но во-первых: это странно, а во-вторых: мне кажется - это неправильно - использовать sh для работы прикладного ПО. Если ничего не получится - буду так делать. Но может быть - есть еще какие-нибудь идеи: почему не работает ioctl?
|
|
|
|
|
Dec 5 2014, 19:09
|
Знающий
   
Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050

|
Цитата(Atridies @ Dec 5 2014, 20:21)  действительно позволила установить новый ip. Но во-первых: это странно, а во-вторых: мне кажется - это неправильно - использовать sh для работы прикладного ПО. Если ничего не получится - буду так делать. Но может быть - есть еще какие-нибудь идеи: почему не работает ioctl? что мешало еще 30 ноября выудить пакет, содержащий исходники ifconfig (или другой утилиты, умеющей менять адрес) из любимого дистрибутива, и посмотреть как там это сделано? зачем изобретать то, что давно надежно и качественно написано до вас? это однокристаллочникам приходится барахтаться, прилаживая ДВС к изобретенному велосипеду..
|
|
|
|
|
Dec 9 2014, 05:47
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Цитата(Atridies @ Dec 5 2014, 21:39)  Но проблема в том, что опять ничего не работает. Запускаю из-под рута. Может разрешений не хватает ? В Вашем коде два системных вызова. Очевидно, один из них завершается ошибкой. Так обработайте должным образом эту ошибку и выведите ее на экран. Тогда и не придется гадать о том, чего программе не хватает. Хотя бы как-то так: Код s = socket(...); if(s < 0) { perror("socket"); exit(1); } ... if(ioctl(...) < 0) perror("ioctl");
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
|
Dec 9 2014, 07:32
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(Atridies @ Dec 5 2014, 18:39)  Но проблема в том, что опять ничего не работает. Посмотрите: Код strace ifconfig eth0 Возможно нужно поднять интерфейс: Код ioctl(s, SIOCGIFFLAGS, &ifr); // флаги интерфейса ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
ioctl(s, SIOCSIFFLAGS, &ifr); close(s);
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|