реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Как установить новый ip-адрес интерфейса программно?
Atridies
сообщение Nov 30 2014, 14:37
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 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;
}


Запускаю, проверяю - адрес не меняется. Что я делают не так? Запускаю эту программу под рутом.
Менять адрес через перезапись в файлах конфигурации - не хочу, т.к. у разных дистрибутивов эти файлы лежат в разных папках.

Заранее спасибо.
Go to the top of the page
 
+Quote Post
krux
сообщение Nov 30 2014, 15:53
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 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


--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
Go to the top of the page
 
+Quote Post
Lagman
сообщение Nov 30 2014, 18:27
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



смотрите как надо вызывать execl, там что то как то не все так просто т.к. при вызове main(int argc, char *argv[])
Цитата
argv[0] указывает на первую символьную строку, которой всегда является имя программы; argv[1] указывает на первый аргумент и так далее.

а в execl присутвует path.
Go to the top of the page
 
+Quote Post
psL
сообщение Nov 30 2014, 19:32
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 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 запускает стартовые скрипты.
Go to the top of the page
 
+Quote Post
alx2
сообщение Dec 1 2014, 06:08
Сообщение #5


Местный
***

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



Добавлю, что установить (изменить) адрес интерфейса также можно через ioctl функцию SIOCSIFADDR.


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
Atridies
сообщение Dec 5 2014, 15:39
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 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 - все задается.
Go to the top of the page
 
+Quote Post
Tanya
сообщение Dec 5 2014, 16:05
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883



Цитата(Atridies @ Dec 5 2014, 18:39) *
Запускаю из-под рута. Может разрешений не хватает ? Но ведь из sh - все задается.

А в программу вставить system (/path_to_script/changeIP.sh)?
Или нужно предварительно вызвать процессор? Я в linux'e не разбираюсь...
Go to the top of the page
 
+Quote Post
Atridies
сообщение Dec 5 2014, 17:21
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468



Команда:
Код
system("ifconfig eth0 10.0.5.20");

действительно позволила установить новый ip. Но во-первых: это странно, а во-вторых: мне кажется - это неправильно - использовать sh для работы прикладного ПО.

Если ничего не получится - буду так делать. Но может быть - есть еще какие-нибудь идеи: почему не работает ioctl?
Go to the top of the page
 
+Quote Post
Tanya
сообщение Dec 5 2014, 17:27
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883



Цитата(Atridies @ Dec 5 2014, 20:21) *
Но во-первых: это странно, а во-вторых: мне кажется - это неправильно - использовать sh для работы прикладного ПО.

Не хотите использовать стандартные подпрограммы (ifconfig) - пишите сами. Только, возможно это придется делать каждый раз для новой системы. А зачем тогда шелловский процессор нужен?
А если бы захотелось письмом извещать, - тоже бы стали для этого свою программу писать?
Go to the top of the page
 
+Quote Post
Jury093
сообщение Dec 5 2014, 19:09
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050



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

что мешало еще 30 ноября выудить пакет, содержащий исходники ifconfig (или другой утилиты, умеющей менять адрес) из любимого дистрибутива, и посмотреть как там это сделано?
зачем изобретать то, что давно надежно и качественно написано до вас?
это однокристаллочникам приходится барахтаться, прилаживая ДВС к изобретенному велосипеду..
Go to the top of the page
 
+Quote Post
alx2
сообщение Dec 9 2014, 05:47
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
psL
сообщение Dec 9 2014, 07:32
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 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);
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th June 2025 - 12:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.03314 секунд с 7
ELECTRONIX ©2004-2016