RFC 903

A Reverse Address Resolution Protocol

πŸ“… published June 1984, from ietf

RFC 903: A Reverse Address Resolution Protocol πŸ¦‹

Okay bestie, the title block is giving old-school Stanford πŸŽ€. This is RFC 903, from the Network Working Group, written in June 1984 by Ross Finlayson, Timothy Mann, Jeffrey Mogul and Marvin Theimer of the Computer Science Department at Stanford University. It's a proposed protocol for the ARPA Internet community. The title block doesn't list anything it obsoletes or updates, so no drama there πŸ’…


Status of this Memo ✨

Okay so this RFC suggests a way for workstations to dynamically find their protocol address (like their Internet Address) when all they know is their hardware address (their attached physical network address) πŸ–₯️

It specifies a proposed protocol for the ARPA Internet community, and it asks for discussion and suggestions for improvements 🫢


I. Introduction πŸ’–

Okay so network hosts like diskless workstations often don't know their protocol addresses when they boot up. Usually they only know their hardware interface addresses πŸ₯Ί To talk using higher-level protocols like IP, they have to figure out their protocol address from some outside source. The problem? There's no standard mechanism for doing that yet 😭

Plummer's "Address Resolution Protocol" (ARP) [1] solves the opposite problem: it resolves a host's hardware address when you already have its protocol address. This RFC proposes a "Reverse Address Resolution Protocol" (RARP) πŸ”₯ Just like ARP, we assume a broadcast medium, such as Ethernet 🌈


II. Design Considerations 🌸

These are the considerations that guided our design of the RARP protocol. Main character energy πŸ‘‘

A. ARP and RARP are different operations. ARP assumes every host knows the mapping between its own hardware address and its protocol address(es). It keeps info about other hosts in a small cache. All hosts are equal in status, so there's no distinction between clients and servers ⭐

RARP is different. It requires one or more server hosts to maintain a database of mappings from hardware address to protocol address, and to respond to requests from client hosts 🧚

B. As we mentioned, RARP needs servers to maintain large databases. Keeping that database in a host's operating system kernel is undesirable, and in some cases impossible πŸ’€ So most implementations will need some form of interaction with a program outside the kernel πŸ“

C. Ease of implementation and minimal impact on existing host software are important ✨ Designing a protocol that forced changes to every host's software, whether or not that host wanted to take part, would be a mistake πŸ™ˆ

D. It's desirable to allow for sharing code with existing software, so we can cut down on overhead and development costs πŸ’œ


III. The Proposed Protocol πŸŽ€

We propose that RARP be specified as a separate protocol at the data-link level. For example, if the medium is Ethernet, RARP packets will have an Ethertype (still to be assigned) that's different from ARP's πŸ¦‹ This recognizes that ARP and RARP are two fundamentally different operations, and not every host supports them equally. The impact on existing systems is minimized, because existing ARP servers won't get confused by RARP packets. It also makes RARP a general facility that can map hardware addresses to any higher-level protocol address 🫢

This approach gives RARP client hosts the simplest implementation, but it gives RARP server hosts the most difficulties. Still, these difficulties shouldn't be insurmountable. Appendix A sketches two possible implementations for 4.2BSD Unix, so check it out πŸ”₯

RARP uses the same packet format as ARP, which looks like this:

   ar$hrd (hardware address space) -  16 bits
   ar$pro (protocol address space) -  16 bits
   ar$hln (hardware address length) - 8 bits
   ar$pln (protocol address length) - 8 bits
   ar$op  (opcode) - 16 bits
   ar$sha (source hardware address) - n bytes,
                                    where n is from the ar$hln field.
   ar$spa (source protocol address) - m bytes,
                                    where m is from the ar$pln field.
   ar$tha (target hardware address) - n bytes
   ar$tpa (target protocol address) - m bytes

ar$hrd, ar$pro, ar$hln and ar$pln are the same as in regular ARP (see [1]) πŸ’…

Let's do an example! Say the 'hardware' addresses are 48-bit Ethernet addresses and the 'protocol' addresses are 32-bit Internet Addresses. So we want to find the Internet Addresses that match known Ethernet addresses 🌈 Then, in each RARP packet, ar$hrd = 1 (Ethernet), ar$pro = 2048 decimal (the Ethertype of IP packets), ar$hln = 6, and ar$pln = 4 🧚

There are two opcodes: 3 ('request reverse') and 4 ('reply reverse'). An opcode of 1 or 2 means the same thing as in [1], so packets with those opcodes can get passed on to regular ARP code. A packet with any other opcode is undefined πŸ“ Like ARP, there are no "not found" or "error" packets, because many RARP servers are free to respond to a request. The sender of a RARP request packet should time out if it doesn't get a reply within a reasonable amount of time ⏰

Here's how the ar$sha, ar$spa, $ar$tha, and ar$tpa fields get interpreted πŸŽ€

When the opcode is 3 ('request reverse'):

  • ar$sha is the hardware address of the sender of the packet.
  • ar$spa is undefined.
  • ar$tha is the 'target' hardware address.
    • If the sender wants to figure out its own protocol address, this will be the hardware address of the sender, just like ar$sha.
  • ar$tpa is undefined.

When the opcode is 4 ('reply reverse'):

  • ar$sha is the hardware address of the responder (the sender of the reply packet).
  • ar$spa is the protocol address of the responder (see the note below).
  • ar$tha is the hardware address of the target, and should be the same as the one given in the request.
  • ar$tpa is the protocol address of the target, which is the desired address πŸ¦‹

Okay, the note: requiring ar$spa in opcode 4 packets to be filled in with the responder's protocol address is purely for convenience πŸ’– For instance, if a system used both ARP and RARP, then the valid protocol-hardware address pair (ar$spa, ar$sha) might mean there's no need for a follow-up ARP request 🧠


IV. References πŸ“š

[1] Plummer, D., "An Ethernet Address Resolution Protocol", RFC 826, MIT-LCS, November 1982.


Appendix A. Two Example Implementations for 4.2BSD Unix 🧚

These implementation sketches outline two different approaches to building a RARP server under 4.2BSD πŸ’»

A. Provide access to data-link level packets outside the kernel. In this approach the RARP server is implemented completely outside the kernel, and it only talks to the kernel to receive and send RARP packets. The kernel has to be modified to give access to these packets, since the 4.2 kernel only allows access to IP packets 😭 One existing mechanism that does this is the CMU "packet-filter" pseudo driver. CMU and Stanford have both used it successfully to build similar "user-level" network servers 🫢

B. Keep a cache of database entries inside the kernel. The full RARP server database lives outside the kernel, maintained by a user process. The RARP server itself runs directly in the kernel and uses a small cache of database entries for its responses. This cache could be the same one used for forward ARP 🌸

The cache gets filled from the actual RARP database through two new ioctls. (These are like SIOCIFADDR, in that they aren't really associated with a specific socket.) One says: "sleep until there's a translation to be done, then pass the request out to the user process." The other says: "enter this translation into the kernel table." So when the kernel can't find an entry in the cache, it puts the request on a (global) queue and then calls wakeup(). The first ioctl sleeps, then pulls the first item off this queue and returns it to the user process πŸ”₯ Since the kernel can't wait around at interrupt level until the user process replies, it has two choices. It can give up and assume the requesting host will retransmit the request packet after a second. Or, if the second ioctl passes a copy of the request back into the kernel, it can formulate and send a response at that time ✨

πŸ“¦ where this page comes from