Изменить IP-адрес источника в сокете sendto()

Моя функция в настоящее время работает правильно, однако она отправляет с моего сервера основной IP-адрес вместо другого.

Вот фрагмент кода:

void *sendpacket(void *par1)
{
        running_threads++;
        int thread_id = (int)par1;
        unsigned long start_ip = htonl(ntohl(start)+(per_thread*thread_id));
        unsigned long end = htonl(ntohl(start)+(per_thread*(thread_id+1)));
        unsigned long w;
        int y;
        unsigned char buf[65536];
        strcpy(buf, "M-SEARCH * HTTP/1.1\r\nHost:239.255.255.250:1900\r\nST:ssdp:all\r\nMan:\"ssdp:discover\"\r\nMX:3\r\n\r\n");
        int sizeofpayload = 90;
        int sock;
        if((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))<0) {
                perror("cant open socket");
                exit(-1);
        }
        for(w=ntohl(start_ip);w<htonl(end);w++)
        {
                struct sockaddr_in servaddr;
                bzero(&servaddr, sizeof(servaddr));
                servaddr.sin_family = AF_INET;
                servaddr.sin_addr.s_addr=htonl(w);
                servaddr.sin_port=htons(1900);
                sendto(sock,(char *)buf,sizeofpayload,0, (struct sockaddr *)&servaddr,sizeof(servaddr));
                bytes_sent+=sizeofpayload;
                scanned++;
                hosts_done++;
                usleep(sleep_between*1000);
        }
        close(sock);
        running_threads--;
        return;
}

Это отправляет пакет в переменную w на порту 1900 с моего IP-адреса сервера по умолчанию, который позволяет называть его 192.168.0.1, однако я хочу, чтобы он отправил пакет с 192.168.1.1, поэтому подделал UDP-пакет для подделки на другой адрес.

servaddr.sin_addr.s_addr=htonl(w);

Обрабатывает адрес назначения, но я изо всех сил пытаюсь изменить исходный IP-адрес.


person user1372896    schedule 14.01.2015    source источник
comment
Я думаю, вам нужны необработанные сокеты для этого.   -  person edmz    schedule 14.01.2015
comment
ПРИМЕЧАНИЕ: bytes_sent+=sizeofpayload; неправильно; для этого вы должны вернуть значение sento().   -  person wildplasser    schedule 14.01.2015
comment
Вам нужна правильная обработка ошибок. Например, если sendto() возвращает -1, вы вообще не отправили ни одного байта.   -  person user207421    schedule 14.01.2015


Ответы (1)


Если 192.168.1.1 является локальным IP-адресом отправляющего ПК, вы можете bind() установить сокет на 192.168.1.1, прежде чем вызывать sendto(). В противном случае вам придется использовать сокет SOCK_RAW (который разрешен только пользователям с правами администратора) и создавать заголовки IP и UDP вручную.

person Remy Lebeau    schedule 14.01.2015