LINUX.ORG.RU

Работа с DHCP


0

0

У меня такой вопрос.В моём приложении, порядок действий такой. { ... 1.Инициализация библиотек. 2.Конфигурация IP адреса через DHCP 2.1. fork(); 2.1.1.Если процесс == парент,тогда продолжить обычную работу с этапа 3. 2.1.2. В другом случае, execve(udhcpc) // udhcpc клиент.Простой бинарник,запускаемый как програма в Линухе 3.Подключение сервера через IP адрес, полученый через DHCP

Программа должна начать этап 3, только после того, как IP адрес получен, но проблемма в том, что получение IP адреса через DHCP процесс достаточно долгий.Поэтому мне нужно ждать, пока DHCP не закончит работу. Можно ли внести какую-нибудь индикацию о том что процесс получения DHCP адреса закончен?

P.S. В принципе у меня есть сорсы, но на данном этапе не хотелось бы их трогать, т.к. библиотека уже откомпилирована и любое изменение внесёт в её конечный размер, а т.к. я пишу для Embedded, то размер здсеь достаточно важный ресурс.Поэтому, если есть возможность без изменения библиотеки,то этот вариант предпочтительнее.

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


А нельзя ли периодически проверять наличии IP адреса? Как только получили, сразу переходим к этапу 3.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

Вообще эта функция предназначена для получения MAC адреса сетевухи, но в закоментированы и другие фичи, такие как и IP адрес

void GetMACAddress(void* buffer,int buffer_size,const char* name) { if(buffer_size!=6) { throw_error("GetMACAddress() - invalid buffer_size"); } struct ifconf Ifc; struct ifreq IfcBuf[MAX_NUM_IFREQ]; struct ifreq *pIfr; int num_ifreq; int i; int fd; struct sockaddr_in addrtmp; unsigned char mac[10]={0};

Ifc.ifc_len = sizeof(IfcBuf); Ifc.ifc_buf = (char *) IfcBuf;

if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { throw_errno("GetMACAddress()/socket()"); }

if ( ioctl(fd, SIOCGIFCONF, &Ifc) < 0) { throw_errno("GetMACAddress()/ioctl():1"); } num_ifreq = Ifc.ifc_len / sizeof(struct ifreq); for ( pIfr = Ifc.ifc_req, i = 0 ; i < num_ifreq; pIfr++, i++ ) { //printf("---===<<<[%d]>>>===---\n", i); if (pIfr->ifr_addr.sa_family != AF_INET) continue; //printf("\n[%d] Is not AF_INET interface! Next information may be incorrect...\n", i); //printf("\n[%d] Name = %s\n", i, pIfr->ifr_name); if(strcmp(pIfr->ifr_name,name)!=0) continue;

if ( ioctl(fd,SIOCGIFHWADDR, pIfr) < 0) { throw_errno("GetMACAddress()/ioctl():2"); } else { /* memcpy(mac,(unsigned char *)&(pIfr->ifr_hwaddr.sa_data),sizeof(struct sockaddr)); printf("\n[%d] MAC = %02X:%02X:%02X:%02X:%02X:%02X\n", i,mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); */ memcpy(buffer,&(pIfr->ifr_hwaddr.sa_data),6); } break;

/* if ( ioctl(fd, SIOCGIFADDR, pIfr) < 0) { perror("\nshowme::Skip ioctl SIOCGIFADDR, error: "); fflush(stderr); } else { memcpy(&addrtmp,&(pIfr->ifr_addr),sizeof(addrtmp)); printf("\n[%d] Address = %s\n",i, inet_ntoa(addrtmp.sin_addr)); }

if ( ioctl(fd, SIOCGIFBRDADDR, pIfr) < 0) { perror("\nshowme::Skip ioctl SIOCGIFBRDADDR, error: "); fflush(stderr); } else { memcpy(&addrtmp,&(pIfr->ifr_broadaddr),sizeof(addrtmp)); printf("\n[%d] BroadAddress = %s\n",i, inet_ntoa(addrtmp.sin_addr)); }

if ( ioctl(fd, SIOCGIFNETMASK, pIfr) < 0) { perror("\nshowme::Skip ioctl SIOCGIFNETMASK, error: "); fflush(stderr); } else { memcpy(&addrtmp,&(pIfr->ifr_addr),sizeof(addrtmp)); printf("\n[%d] MaskAddress = %s\n",i, inet_ntoa(addrtmp.sin_addr)); }

if ( ioctl(fd, SIOCGIFFLAGS, pIfr) < 0) { perror("\nshowme::Skip ioctl SIOCGIFFLAGS, error: "); fflush(stderr); } else { printf("\n[%d] IFF_UP=%s\n",i, pIfr->ifr_flags&0x1?"ON":"OFF"); printf("\n[%d] IFF_BROADCAST=%s\n",i, pIfr->ifr_flags&0x2?"ON":"OFF"); printf("\n[%d] IFF_DEBUG=%s\n",i, pIfr->ifr_flags&0x4?"ON":"OFF"); printf("\n[%d] IFF_LOOPBACK=%s\n",i, pIfr->ifr_flags&0x8?"ON":"OFF"); printf("\n[%d] IFF_P2P=%s\n",i, pIfr->ifr_flags&0x10?"ON":"OFF"); printf("\n[%d] IFF_NOTRAILERS=%s\n",i, pIfr->ifr_flags&0x20?"ON":"OFF"); printf("\n[%d] IFF_RUNNING=%s\n",i, pIfr->ifr_flags&0x40?"ON":"OFF"); printf("\n[%d] IFF_NOARP=%s\n",i, pIfr->ifr_flags&0x80?"ON":"OFF"); } */ } }

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

Да.Спасибо конечно.Но это все работа с существующим IP.Мне же нужна общая концепция,как решить мою задачу.

rapa
() автор топика
Ответ на: комментарий от rapa

Я так понял, что нужно просто дождаться когда у определенного сетевого интерфейса появится IP адрес, и после этого перейти к этапу 3.

Подобную операцию проверки наличия IP адреса можно делать в цикле с засыпанием на определенный интервал.

pathfinder ★★★★
()

А нельзя просто подождать когда udhcpc завершится?

mqspi
()
Ответ на: комментарий от pathfinder

Если задача заключается не в этом, то можешь более подробно её объяснить. А то не совсем понятно что требуется.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

>Подобную операцию проверки наличия IP адреса можно делать в цикле с засыпанием на определенный интервал.

Можно,но время получения адреса не фиксированное.Т.е. иногда это сразу,иногда надо ждать секунд 15.

>А нельзя просто подождать когда udhcpc завершится?

Тоже можно,но даже после получения IP-шки,udhcpc остаeтся в списке процессов.

>Если задача заключается не в этом, то можешь более подробно её объяснить. А то не совсем понятно что требуется.

Бегут 2 процесса параллельно: 1 и 2. Процесс 2 подлючается к DHCP серверу и получает от него IP адрес, а процесс 1 должен ждать пока IP адрес не будет получен, т.к. процесс 1 запускает сервер и для этого ему нужен IP. Как реализаовать ожидание?

P.S. Подключение к DHCP я реализовываю через запуск бинарника функцией execve(...).

rapa
() автор топика
Ответ на: комментарий от rapa

Судя по ману, udhcpc после получения лизы на адрес может запускать шелл-скрипт. Можно сделать так, чтобы этот скрипт сообщал твоей программе, что адрес успешно получен. ИМХО самый простой способ - повешать в программе обработчик на какой-нибудь сигнал, например SIGUSR1, а в скрипте делать что-то типа

kill -s USR1 $YOURPROGRAMPID

Deleted
()
Ответ на: комментарий от rapa

> Тоже можно,но даже после получения IP-шки,udhcpc остаeтся в списке процессов.

Ну все равно твой дочерний процесс помирает - udhcpc форкается при успешном завершении. Имхо проще всего через waitpid подождать и на код завершения поглядеть.

mqspi
()
Ответ на: комментарий от rapa

>Можно,но время получения адреса не фиксированное.Т.е. иногда это сразу,иногда надо ждать секунд 15.

А в чем проблема? Просыпайся каждые 200 милисекунд и смотри не появился ли IP адрес у сетевухи. Если не появился, то засыпай на следующие 200 милисекунд т. д. Боятся, того что это съест много процессорного времени нестоит. И тут без разницы сколько времени надо на получение IP адреса одну секунду или 15 секунд или вообще много-много часов. Разница будет лишь в числе холостых проверок.

pathfinder ★★★★
()
Ответ на: комментарий от rapa

> Можно,но время получения адреса не фиксированное.Т.е. иногда это сразу,иногда надо ждать секунд 15.

do
{
  usleep(100000);
} while(check_ip_assigned() == false);

bvvv
()
Ответ на: комментарий от bvvv

>do { usleep(100000); } while(check_ip_assigned() == false);

Спасибо.Это сработало,только фактически,что я сделал,я ждал пока udhcpc получит адрес, а в конце посылал сигнал в главный процесс.А там я его ловил. Тема закрыта. Один совет,если у кого-то будет такая же проблема.Я ждал так: while(flag ==0) { } Чтобы это сработало,либо отключайте оптимизацию,либо внесите какой-то оператор в { }.

rapa
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.