How to ignore your own broadcast udp packets

て烟熏妆下的殇ゞ 提交于 2019-11-28 12:11:06

Well at start-up you could broadcast a different message with random (but tracked) value, then wait for that message, to discover your own address, from then on, you can send normal messages, ignoring your sourced messages.

getsockname (function documentation) can discover the local IP address associated with a particular socket. If you call this on the socket you're using to send the broadcast, you should see the same IP address you'll see returned by recvfrom.

On linux, you can get the IP address of a given interface using ioctl with the SIOCGIFADDR option. I don't think this works for Windows, though. For that, you'll have to do something goofy like this.

Search for scoket options and see whether these works: IP_MULTICAST_LOOP,IP_BLOCK_SOURCE

(I am presuming you are working on Windows)

GetIpAddrTable does exactly that! It returns data about all your network interfaces, the IP address is among them. There is some trickery in getting them, but not more than in the rest of Winsocks.

Here is a ready to compile 54 lines example that prints all your network interfaces with IP and Network masks, and also filters for your local callback (127.0.0.1) since you most likely don't want that, and it is always there, so you can't just ignore it:

(worked with msvc 19, windows 10, link against Iphlpapi.lib and Ws2_32.lib)

#include "stdio.h"
#include "Winsock2.h"
#include "Iphlpapi.h"

int main(){
    int error;

    ULONG size = 0;
    MIB_IPADDRTABLE* meta_table = nullptr;

    error = GetIpAddrTable(meta_table, &size, false);
    if(error != ERROR_INSUFFICIENT_BUFFER)
        return -1;

    meta_table = (MIB_IPADDRTABLE*)malloc(size);

    error = GetIpAddrTable(meta_table, &size, false);
    if(error != NO_ERROR)
        return -1;

    int os_interface_count = meta_table->dwNumEntries;

    for(int i = 0; i < os_interface_count; i++){

        printf("interface:\n");

        {
            in_addr mask;
            in_addr address;
            address.S_un.S_addr = meta_table->table[i].dwAddr;
            mask.S_un.S_addr = meta_table->table[i].dwMask;

            printf("index:     %d\n", meta_table->table[i].dwIndex);
            printf("address:   %s\n", inet_ntoa(address));
            printf("mask:      %s\n", inet_ntoa(mask));
        }

        {
            in_addr callback_address;
            callback_address.S_un.S_un_b.s_b1 = 127;
            callback_address.S_un.S_un_b.s_b2 = 0;
            callback_address.S_un.S_un_b.s_b3 = 0;
            callback_address.S_un.S_un_b.s_b4 = 1;

            if(meta_table->table[i].dwAddr == callback_address.S_un.S_addr)
                printf("local callback!\n");

        }

    }

    free(meta_table);
    return 0;
}

producing this output on my machine:

interface:
index:     7
address:   192.168.56.1
mask:      255.255.255.0
interface:
index:     1
address:   127.0.0.1
mask:      255.0.0.0
local callback!
interface:
index:     11
address:   192.168.178.181
mask:      255.255.255.0

The only really weird thing is the first call to GetIpAddrTable, which just gives you the size you need to allocate for the buffer. I think the rest of the code is pretty self explanatory, if not I'm here for questions. (I don't hav 50 Rep, so I don't know if I will be able to reply to questions, Thanks Stackoverflow!)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!