2

Ive been trying to create a .NET 6.0 program which uses a specific (Arch) linux network interface to make http requests for 2 days now, ive read #23267, tried understanding the code examples provided in it and many stack overflow solutions but none of them worked for me. I am also using IPv6 because for some reason both wlan0 (wifi) and enp3s0 (ethernet) have the same private IPv4 even though theyre on different networks, but this is apparently not too uncommon so since the IPv6's arent the same I went with them

Currently this is the code i have:

using System.Net.NetworkInformation;
using System.Net.Sockets;

foreach (var iface in NetworkInterface.GetAllNetworkInterfaces())
{
    if ((iface.Name == "wlan0"))
    {
        );
        foreach (var ua in iface.GetIPProperties().UnicastAddresses)
        {
            if (ua.Address.AddressFamily == AddressFamily.InterNetwork) continue; 

            Console.WriteLine($"\x1b[36m{ua.Address.AddressFamily} Address: {ua.Address.ToString().Split("%")[0]}\x1b[0m");

            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri($"http://[{ua.Address}]:0/"); // same thing happens with splitting ua.Address

            try {
                var res = await client.GetAsync("https://ifconfig.me");
                Console.WriteLine(await res.Content.ReadAsStringAsync());
            } catch (Exception e) { Console.WriteLine(e.Message); }
        }
    }
}

The output of my program:

InterNetworkV6 Address: fe80::eaf:aec2:7d24:82d4
***.***.***.27

vs the correct wlan0 public IPv4 with curl --interface wlan0 ifconfig.me:

***.***.***.4

The client.BaseAddress part seems to do nothing, since i get the same result with and without it even though the IPv6 im specifying in the URI is definitely the wlan0 IPv6. So, trying another solution and rewriting the client:

HttpClient client = new HttpClient(new SocketsHttpHandler() {
    ConnectCallback = async (context, cancellationToken) =>
    {
        Socket socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
        socket.Bind(new IPEndPoint(ua.Address, 0));
        socket.NoDelay = true;
        try
        {
            await socket.ConnectAsync(context.DnsEndPoint, cancellationToken).ConfigureAwait(false);
            return new NetworkStream(socket, true);
        }
        catch
        {
            socket.Dispose();
            throw;
        }
    }
});

This makes my program give this output:

InterNetworkV6 Address: fe80::eaf:aec2:7d24:82d4
No data available (ifconfig.me:443)

Now, testing on my laptop which also has Arch Linux installed, with 2 different wifi adapters where each is connected to a different network and has a unique private IPv4 address; One is a USB adapter and its called wlp0s20f0u2 and the other is the built in one, called wlp2s0. Changing my code from skipping IPv4 addresses to skipping IPv4 (the continue statements) and removing the AddressFamily specification from the Socket initialization - the plugged in adapter works fine and is the default option (gets chosen by a plain new HttpClient()) but the built in adapter ends up timing out after the default 100 seconds and i don't see any requests being made in the wlp2s0 interface through wireshark. This also happened on my PC with IPv4, before i somehow made both private IPv4's the same. And again, curl --interface wlp2s0 ifconfig.me works fine

user1623521
  • 340
  • 1
  • 16
demented
  • 76
  • 5
  • FYI: `client.BaseAddress` sets the base address for the request. For example: `client.BaseAddress = new Uri("https://www.example.com/test");` when used with `await client.GetAsync("page/here.htm");` would make a request to `https://www.example.com/test/page/here.htm`. – ProgrammingLlama Sep 20 '22 at 02:21
  • hm yeah i guessed thats what it does but ive seen some people suggest it as a way to do what im trying to do so thats why i included that here i guess @DiplomacyNotWar – demented Sep 20 '22 at 02:22
  • I've tried [this answer](https://stackoverflow.com/a/66681784/3181933), which seems to be what you based your second example on, and at least over IPv4 it seems to use the correct interface (I checked with Wireshark). – ProgrammingLlama Sep 20 '22 at 03:00
  • it might work through ipv4 but sadly ipv6 is the only unique private ip i have between the 2 networks since i havent been able to figure out how to change the private ipv4 for my machine on one of the networks and i think im not able to do it through my routers admin page - also ipv6 might be a more stable option because of this, and im guessing curl used ipv6 too since their --interface specification still works even with 2 of my networks sharing the same private ipv4 @DiplomacyNotWar – demented Sep 20 '22 at 03:08
  • Is https://ifconfig.me definitely available on IPv6? I've put the URL into a few IPv6 validators and it seems that the site isn't IPv6 ready? – ProgrammingLlama Sep 20 '22 at 03:11
  • looks like its not but ifconfig.co apparently is and for that one i get "Network is unreachable" for both http and https but it also doesnt work with curl -6 - Couldn't connect to server @DiplomacyNotWar – demented Sep 20 '22 at 03:22
  • what version of .NET are you using? Mono? dotnet? what version? – user1623521 Sep 22 '22 at 05:00
  • 1
    i didnt realise i havent specified that, .NET Core 6.0 @user1623521 i updated the post – demented Sep 22 '22 at 17:29
  • Address is an array where on most machines index zero is IPV6 and index one is IPV4. – jdweng Oct 08 '22 at 20:16

0 Answers0