Articles tagged #rust

Thumbnail for The builder pattern, and a macro that keeps FFI code DRY

The builder pattern, and a macro that keeps FFI code DRY

Our ping API is simple, but it’s also very limited:

pub fn ping(dest: ipv4::Addr) -> Result<(), String> // called as: ping(ipv4::Addr([8, 8, 8, 8])).unwrap();

It doesn’t allow specifying the TTL (time to live) of packets, it doesn’t allow specifying the timeout, it doesn’t let one specify the data to send along, and it doesn’t give us any kind of information on the reply.

Thumbnail for A simple ping library, parsing strings into IPv4 address

A simple ping library, parsing strings into IPv4 address

We’ve just spent a lot of time abstracting over LoadLibrary, but we still have all the gory details of the Win32 ICMP API straight in our main.rs file! That won’t do.

This time will be much quicker, since we already learned about carefully designing an API, hiding the low-level bits and so on.

Let’s add an icmp module to our program. Actually, we’ve been dealing with an IPAddr all this time, it also sounds like it could use its own package:

Thumbnail for Designing and implementing a safer API on top of LoadLibrary

Designing and implementing a safer API on top of LoadLibrary

It’s refactor time!

Our complete program is now about a hundred lines, counting blank lines (see the end of part 3 for a complete listing).

While this is pretty good for a zero-dependency project (save for pretty-hex), we can do better.

First off, concerns are mixed up. In the same file, we:

  • Expose LoadLibraryA / GetProcAddress
  • Expose the Win32 ICMP API
Thumbnail for FFI-safe types in Rust, newtypes and MaybeUninit

FFI-safe types in Rust, newtypes and MaybeUninit

It’s time to make sup, our own take on ping, use the Win32 APIs to send an ICMP echo. Earlier we discovered that Windows’s ping.exe used IcmpSendEcho2Ex. But for our purposes, the simpler IcmpSendEcho will do just fine.

As we mentioned earlier, it’s provided by IPHLPAPI.dll, and its C declaration is:

IPHLPAPI_DLL_LINKAGE DWORD IcmpSendEcho( , , , , , , , );
Thumbnail for Windows dynamic libraries, calling conventions, and transmute

Windows dynamic libraries, calling conventions, and transmute

So, how does ping.exe actually send a ping? It seems unrealistic that ping.exe itself implements all the protocols involved in sending a ping. So it must be calling some sort of library. Also, since it ends up talking to the outside world via a NIC (network interface controller), the kernel is probably involved at some point.

In reading files the hard way - part 2, we learned about dynamic libraries (like libc), and the Linux kernel, and how syscalls allowed us to ask the Linux kernel to do our bidding. For this series, we’re going to have to look at the Windows equivalents.

Thumbnail for Making our own ping

Making our own ping

When I launched my Patreon, I vowed to explain how computers work. But in 2019, computers rarely work in isolation. So let’s take the time to write a few articles about how computers talk to each other.

Declarative memory management

It feels like an eternity since I’ve started using Rust, and yet I remember vividly what it felt like to bang my head against the borrow checker for the first few times.

I’m definitely not alone in that, and there’s been quite a few articles on the subject! But I want to take some time to present the borrow checker from the perspective of its benefits, rather than as an opponent to fend with.

Thumbnail for Reading files the hard way - Part 3 (ftrace, disk layouts, ext4)

Reading files the hard way - Part 3 (ftrace, disk layouts, ext4)

So far, we’ve seen many ways to read a file from different programming languages, we’ve learned about syscalls, how to make those from assembly, then we’ve learned about memory mapping, virtual address spaces, and generally some of the mechanisms in which userland and the kernel interact.

But in our exploration, we’ve always considered the kernel more or less like a “black box”. It’s time to change that.

Go back to the homepage.