KallistiOS IPv4 DHCP Issues

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 85
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Wed Jan 05, 2011 4:25 pm
Has thanked: 4 times
Been thanked: 39 times

KallistiOS IPv4 DHCP Issues

Post by Moopthehedgehog »

Hello,

I'm trying to get the KOS network examples to work properly using DHCPv4 to get the Dreamcast an IP address with a Broadband Adapter. I've managed to get one of my Dreamcasts (the one whose isp-settings network example reports that DHCP is stored in the flashrom) to wait 60 seconds per genwait_wait() in net_dhcp_request(), but it never gets an IPv4 address. The basic networking example, which I've modified slightly to print to the screen--I have to boot via CDs instead of dcload-ip to do all this, and I am using the INIT_NO_DCLOAD init flag--reports UDP send errors and my PC does not show any DHCP request packets being sent over the network. My Router agrees: no DHCPv4 leases are given to the Dreamcast.

What's kind of crazy is that IPv6 works totally fine with router solicitations, and I was able to run and communicate with the IPv6 UDP Echo example no problem (0.0.0.0 was the IPv4 address, though...).

Any ideas where the hangup is? It looks like packets aren't leaving the Dreamcast, but I can't figure out why. Ideally I'd like to be able to override whatever KOS is doing with the flashrom settings and force the machine always use DHCP, but I'm trying to avoid modifying the KOS backend if possible.
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 85
Joined: Wed Jan 05, 2011 4:25 pm
Has thanked: 4 times
Been thanked: 39 times

Re: KallistiOS IPv4 DHCP Issues

Post by Moopthehedgehog »

Oh, I think I see a problem in KOS. The UDP packet send failed statistic that comes from the basic networking demo gets incremented in only one place, "net_udp_send_raw()," which is an IPv6 function. For some reason IPv4 packets are being processed through "net_udp_send_raw()," which looks like this:
Spoiler!

Code: Select all

static int net_udp_send_raw(netif_t *net, const struct sockaddr_in6 *src,
                            const struct sockaddr_in6 *dst, const uint8 *data,
                            size_t size, uint32_t flags, int hops,
                            uint32_t iflags, int proto, uint16_t cscov) {
    uint8 buf[size + sizeof(udp_hdr_t)];
    udp_hdr_t *hdr = (udp_hdr_t *)buf;
    uint16 cs;
    int err;
    struct in6_addr srcaddr = src->sin6_addr;

    (void)flags;

    if(!net) {
        net = net_default_dev;

        if(!net) {
            errno = ENETDOWN;
            ++udp_stats.pkt_send_failed;
            return -1;
        }
    }

    if(IN6_IS_ADDR_UNSPECIFIED(&src->sin6_addr)) {
        if(IN6_IS_ADDR_V4MAPPED(&dst->sin6_addr)) {
            srcaddr.__s6_addr.__s6_addr16[5] = 0xFFFF;
            srcaddr.__s6_addr.__s6_addr32[3] =
                htonl(net_ipv4_address(net->ip_addr));

            if(srcaddr.__s6_addr.__s6_addr32[3] == INADDR_ANY) {
                errno = ENETDOWN;
                ++udp_stats.pkt_send_failed;
                return -1;
            }
        }
        else {
            if(IN6_IS_ADDR_LOOPBACK(&dst->sin6_addr)) {
                srcaddr = in6addr_loopback;
            }
            else if(IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr) ||
                    IN6_IS_ADDR_MC_LINKLOCAL(&dst->sin6_addr)) {
                srcaddr = net->ip6_lladdr;
            }
            else if(net->ip6_addr_count) {
                /* Punt and pick the first non-link-local address */
                srcaddr = net->ip6_addrs[0];
            }
            else {
                errno = ENETDOWN;
                ++udp_stats.pkt_send_failed;
                return -1;
            }
        }
    }

    memcpy(buf + sizeof(udp_hdr_t), data, size);
    size += sizeof(udp_hdr_t);

    hdr->src_port = src->sin6_port;
    hdr->dst_port = dst->sin6_port;
    hdr->checksum = 0;

    /* Is this UDP or UDP-Lite? */
    if(proto == IPPROTO_UDP) {
        hdr->length = htons(size);

        if(!(iflags & UDPSOCK_NO_CHECKSUM)) {
            cs = net_ipv6_checksum_pseudo(&srcaddr, &dst->sin6_addr, size,
                                          proto);
            hdr->checksum = net_ipv4_checksum(buf, size, cs);
        }
    }
    else {
        if(cscov <= size) {
            hdr->length = htons(cscov);
        }
        else {
            hdr->length = 0;
            cscov = size;
        }

        cs = net_ipv6_checksum_pseudo(&srcaddr, &dst->sin6_addr, size, proto);
        hdr->checksum = net_ipv4_checksum(buf, size, cs);
    }

    /* Pass everything off to the network layer to do the rest. */
    err = net_ipv6_send(net, buf, size, hops, proto, &srcaddr,
                        &dst->sin6_addr);

    if(err < 0) {
        ++udp_stats.pkt_send_failed;
        return -1;
    }
    else {
        ++udp_stats.pkt_sent;
        return size - sizeof(udp_hdr_t);
    }
}


Obviously that's not gonna work!


Edit 1: Nevermind, I jumped to conclusions a bit too soon here. KOS is wrapping up IPv4 in IPv6 and processing it that way... Wow, this is really frustrating to debug...
Last edited by Moopthehedgehog on Fri Nov 15, 2019 5:01 pm, edited 2 times in total.
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5652
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: KallistiOS IPv4 DHCP Issues

Post by BlueCrab »

Well, that's certainly strange and not behavior that I've seen before with regard to DHCP -- I've seen my router completely ignore the requests when testing (because I sent them too often), but I've never seen the system not send them out.
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 85
Joined: Wed Jan 05, 2011 4:25 pm
Has thanked: 4 times
Been thanked: 39 times

Re: KallistiOS IPv4 DHCP Issues

Post by Moopthehedgehog »

Ah! The packets are getting eaten by this check in net_udp.c:

Spoiler!

if(srcaddr.__s6_addr.__s6_addr32[3] == INADDR_ANY) {
errno = ENETDOWN;
++udp_stats.pkt_send_failed;
dbglog(DBG_DEBUG, "inaddr_any\n"); // temp <-- I added this line to check where the error is getting incremented
return -1;
}

An IP of 0.0.0.0 is valid for the duration of IPv4 DHCP. I see the Nintendo Wii U and a Mac Mini doing it regularly, for example. KOS should not be eating initial DHCPv4 packets like this--when a device is new on the network, it needs to have an initial IP of something to talk to the router. This Wikipedia page shows that 0.0.0.0/8 is reserved for local network communication, and is only valid as a source address.

Update: Commenting out that check works! I get IPv4 DHCP now! Router agrees, I have a DHCP lease assigned to KallistiOS on a Dreamcast. :)
Now on to what I was really trying to do in the first place...
DCLOAD-IP w/DHCP!!!
These users thanked the author Moopthehedgehog for the post:
ThePerfectK
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5652
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: KallistiOS IPv4 DHCP Issues

Post by BlueCrab »

Interesting... I'm not sure why it would have ever worked at all if that's how it's broken. Weird... Well, thanks for figuring it out. :)

I'll rig up a better fix for it than just commenting that out the next time I get a chance to work on things.
Post Reply