Перейти к содержанию
    

Как установить новый ip-адрес интерфейса программно?

Здравствуйте!

 

Есть задача - установить новый 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;
}

 

Запускаю, проверяю - адрес не меняется. Что я делают не так? Запускаю эту программу под рутом.

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

 

Заранее спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

зависит от того, чем управляются интерфейсы в системе в принципе. у разных дистрибутивов разные подходы, поэтому придётся адаптироваться.

Если в системе установлен пакет NetworkManager, то надо работать через него, вернее с ним через D-Bus. Потому как он может в любой момент изменить то что вы там наделали вручную без его ведома.

Если через скрипты, то либо дорабатывать скрипты, либо убирать их совсем и делать все дела самому.

 

в крайнем случае:

https://www.kernel.org/pub/linux/utils/net/...2-3.17.0.tar.gz

смотреть исходник ip/ipaddr.c

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

смотрите как надо вызывать execl, там что то как то не все так просто т.к. при вызове main(int argc, char *argv[])

argv[0] указывает на первую символьную строку, которой всегда является имя программы; argv[1] указывает на первый аргумент и так далее.

а в execl присутвует path.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 запускает стартовые скрипты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ответы. Несколько дней понадобилось, чтобы разобраться с 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 - все задается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Запускаю из-под рута. Может разрешений не хватает ? Но ведь из sh - все задается.

А в программу вставить system (/path_to_script/changeIP.sh)?

Или нужно предварительно вызвать процессор? Я в linux'e не разбираюсь...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Команда:

system("ifconfig eth0 10.0.5.20");

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

 

Если ничего не получится - буду так делать. Но может быть - есть еще какие-нибудь идеи: почему не работает ioctl?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Не хотите использовать стандартные подпрограммы (ifconfig) - пишите сами. Только, возможно это придется делать каждый раз для новой системы. А зачем тогда шелловский процессор нужен?

А если бы захотелось письмом извещать, - тоже бы стали для этого свою программу писать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Если ничего не получится - буду так делать. Но может быть - есть еще какие-нибудь идеи: почему не работает ioctl?

что мешало еще 30 ноября выудить пакет, содержащий исходники ifconfig (или другой утилиты, умеющей менять адрес) из любимого дистрибутива, и посмотреть как там это сделано?

зачем изобретать то, что давно надежно и качественно написано до вас?

это однокристаллочникам приходится барахтаться, прилаживая ДВС к изобретенному велосипеду..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но проблема в том, что опять ничего не работает.

Запускаю из-под рута. Может разрешений не хватает ?

В Вашем коде два системных вызова. Очевидно, один из них завершается ошибкой. Так обработайте должным образом эту ошибку и выведите ее на экран. Тогда и не придется гадать о том, чего программе не хватает. Хотя бы как-то так:

s = socket(...);
if(s < 0) {
  perror("socket");
  exit(1);
}
...
if(ioctl(...) < 0)
  perror("ioctl");

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но проблема в том, что опять ничего не работает.

Посмотрите:

strace ifconfig eth0

 

Возможно нужно поднять интерфейс:

        ioctl(s, SIOCGIFFLAGS, &ifr);
        // флаги интерфейса
        ifr.ifr_flags |= IFF_UP | IFF_RUNNING;

        ioctl(s, SIOCSIFFLAGS, &ifr);
        close(s);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...