VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

Anyone knows how to detect the assignment of a IP addreds(IPv4) from raw TCP/IP packets? I want to make the IP filter within UniPCemu's server able to use DHCP(by analyzing the incoming/outgoing packets) to filter the IP addresses(while having a fallback to the current static IPv4 filter(done on ethernet level/IPv4 level atm)).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 13, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

Do you know how to use Wireshark? You can load a pcap file with DHCP requests and read the raw packet data.

All hail the Great Capacitor Brand Finder

Reply 2 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

Nope. I do have some other tool(Microsoft Network Monitor 3.4) installed with similar capabilities on my Windows 10 development system though. As far as I can find of the DHCP protocol it should be a simple 4-step detection process. But the main problem might be to keep track of the different DHCP servers, if there are multiple ones? I know the basic process(https://mrncciew.com/2012/12/27/understanding-dhcp/), but I'm not sure about the incoming port filter and outgoing port filter. As well as the 'bootp' part(is it that content in the screen captures or is it a wrapper like IP/UDP?). The screen captures show the generic layout within the packet, but I don't have exact typedefs or anything to make those). How much is needed to retrieve basic IP information(for later use in the server's IP filters to adjust it from it's default static IP filtering(currently filters SETTINGS.INI IP as well as (broadcast) MAC and broadcast IP). I simply need it to sniff the communication between the client and the server to make it adjust said static IP based on the DHCP packets that are sent(by the client through the server to pcap send) or received(through packet capture, filtered by the app(see above) and sent to the client over it's TCP I/O bytestream in SLIP encoding).

So far the server already works with static IP and lots of incoming packets(both for the host and guest system), so I want it to be able to filter it further by providing a dynamic filter that adjusts to the DHCP settings, when it's used by the client. It's relatively easy to add a simple incoming/outgoing packet analyzer for it, but I'll need the exact data structures that are within the IPv4/UDP/BOOTP/DHCP parts to analyze them. Also, I need some way to deal with multiple offers from multiple DHCP servers, if any exist.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 13, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

What about implementing a form of DHCP proxy? I suspect you could leverage off the shelf BSD or ISC licensed software to do it on the host OS.

All hail the Great Capacitor Brand Finder

Reply 4 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++
gdjacobs wrote:

What about implementing a form of DHCP proxy? I suspect you could leverage off the shelf BSD or ISC licensed software to do it on the host OS.

Or I could be doing something more simple: a simple DHCP relay agent(As it's called here).

That DHCP relay agent is pretty much what my SLIP server does as well(except it passes through all IPv4 packets to the modem that's configured).

Although the multiple DHCP offers filter could be made more simply: only take one offer from a DHCP server(matching transaction ID etc.), then blocking all other offers from being sent to the client. That way, it can simply keep track of the entire transaction without much memory allocation and multiple(who knows how many) buffers for DHCP offers, as well as making tracking it easier? So after sending a discover(saving it), take the first offer(saving it), then the request(saving it) and final ack(saving it, then loading the IP filter settings from those 4 packets). Of course the DHCP release restores the default(static) IP address back in place(simple catch-all for the host PC). The non-DHCP way currently still assigns the same IP as the host(using a text transaction before starting SLIP-mode(Windows 95) using the login script on the repository, or manually configured(with Arachne)).

Edit: Of course I'll also need to figure out the checksums, which aren't implemented in the SLIP server yet.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 13, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

The only issue with a relay agent is that it will be bypassed on lease renewal and the agent won't receive notice of a dhcp release. I think a proxy agent will give you complete visibility of all transactions and is the best option to keep your filter rules current.

All hail the Great Capacitor Brand Finder

Reply 6 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

In what way is that bypassed? Since all packets can be seen by the server(all packets that are sent&received by the client), can't it look at any DHCP packets and detect any of those?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 7 of 13, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

Yes, except you would need a custom service to inspect those packets as they cross the (virtual) wire. A proxy agent will keep track of active leases by design.

With proxying, the dhcp client will issue any instructions to the agent (including releases and renewals) which then passes them upstream, and because the proxy by definition includes a full dhcp server, it can maintain a lease table for anything in the VM which can be used by your filter service to open or close the firewall as needed.

All hail the Great Capacitor Brand Finder

Reply 8 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

Can't it just pass through all sent packets to the modem(of course saving them in a temporary buffer for comparison with the ACK), and when receiving the ACK from the modem(at which point it has both the sent discovery/request/renew/release packet AND it's accompanying offer/acnowledge the modem sent back). It can then, when receiving the offer, block all other offers from being received to make sure the client will use that one. When receiving the ACK for the request, it will change it's incoming packet filter to instead of the currently static IP, use said IP as the new filter. When receiving an ACK for a release, it will simply revert the IP filter back to the default static IP(which will cause it to spam it's host's packets once more until a new DHCP request/ack/request/ack sets it up again)?

Would that work?

I have most information about the packet structure(except the DHCP parameters structure themselves) already, except their various checksum fields. How are the IP/TCP/UDP checksums calculated(in plain C)? Do they all do the same(Add all bytes of the layer to a 17-bit word value, adding bit 17 to bit 0 after adding each one and then clearing said bit) as far as I understand?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 9 of 13, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

There's lots of ways you could do it. There was nothing inherently wrong with the original idea of sniffing the packets direct off the wire. To my thinking, using a proxy is just easier as it requires a very straightforward filter and a minimum of work implementing the proxy (either via an off the shelf stack or by using existing protocol libraries).

All hail the Great Capacitor Brand Finder

Reply 10 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

Does anyone know how to calculate the checksums within the IP/UDP packet headers? I'll need that for the server to verify correct sent/received packets, after all(since incorrect packets should be ignored).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 11 of 13, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

My take is: assemble the appropriate data into a pseudo header:

The pseudo header conceptually prefixed to the UDP header contains the
source address, the destination address, the protocol, and the UDP
length.

Then begin to one's complement sum each 16 bits of the pseudo header. Roll any carry bit over into the next sum. Once the pseudo header is summed, one's complement sum the resulting 16 bits down to one bit and compare.

All hail the Great Capacitor Brand Finder

Reply 12 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

One simple question: is that the same process as with the IPv4 header? I've already found some code that generates a checksum for that?

/*
* Return checksum for the given data.
* Copied from FreeBSD
*/
static unsigned short
in_cksum(unsigned short *addr, int len)
{
register int sum = 0;
u_short answer = 0;
register u_short *w = addr;
register int nleft = len;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1)
{
*(u_char *)(&answer) = *(u_char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}

From http://github.com/samueldotj/dhcp-client.git, file dhcp-client.c.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 13 of 13, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

I think so, although make sure the pseudoheader used contains the data specified for your application. The sum above is probably calculated using two's complement where UDP uses one's complement, but they take care of the carry around so it's probably fine.

I was under the understanding earlier that the final 16 bit sum is folded down to a single bit, but that's actually not correct. The checksum in the UDP header is 16 bits.

All hail the Great Capacitor Brand Finder