Search code examples
csocketssendto

Change Source IP in socket sendto()


My function currently works correctly, however It's sending from my servers main IP address instead of another one.

Here is the snippet of code:

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;
}

This sends a packet to the variable w, on port 1900 from my default server IP lets call it 192.168.0.1 however I want it to send the packet from 192.168.1.1 so forging the UDP packet to spoof to another address.

servaddr.sin_addr.s_addr=htonl(w);

Handles the destination address but I'm struggling to edit the source IP address.


Solution

  • If 192.168.1.1 is a local IP of the sending PC, you can bind() the socket to 192.168.1.1 before than calling sendto(). Otherwise, you have to use a SOCK_RAW socket (which is restricted to admin users only) and create the IP and UDP headers manually.