To complete the message from @mr.spuratic: the text from RFC 791 is:
Loose Source and Record Route
+--------+--------+--------+---------//--------+
|10000011| length | pointer| route data |
+--------+--------+--------+---------//--------+
Type=131
The loose source and record route (LSRR) option provides a means
for the source of an internet datagram to supply routing
information to be used by the gateways in forwarding the
datagram to the destination, and to record the route
information.
The option begins with the option type code. The second octet
is the option length which includes the option type code and the
length octet, the pointer octet, and length-3 octets of route
data. The third octet is the pointer into the route data
indicating the octet which begins the next source address to be
processed. The pointer is relative to this option, and the
smallest legal value for the pointer is 4.
A route data is composed of a series of internet addresses.
Each internet address is 32 bits or 4 octets. If the pointer is
greater than the length, the source route is empty (and the
recorded route full) and the routing is to be based on the
destination address field.
If the address in destination address field has been reached and
the pointer is not greater than the length, the next address in
the source route replaces the address in the destination address
field, and the recorded route address replaces the source
address just used, and pointer is increased by four.
The recorded route address is the internet module's own internet
address as known in the environment into which this datagram is
being forwarded.
This procedure of replacing the source route with the recorded
route (though it is in the reverse of the order it must be in to
be used as a source route) means the option (and the IP header
as a whole) remains a constant length as the datagram progresses
through the internet.
This option is a loose source route because the gateway or host
IP is allowed to use any route of any number of other
intermediate gateways to reach the next address in the route.
Must be copied on fragmentation. Appears at most once in a
datagram.
Possible confusion arises from the reuse of the the expression "source address". An IP packet has a source address field and a destination address field, which are NOT part of this option. The contents of the option (route data
in the diagram above) consist in a sequence of IPv4 addresses, and the pointer
field is an index within that list.
When the packet is first emitted, the sender wishes (by this option) to direct the packet to go through a sequence of designated routers. Let's call i1, i2... in the IP addresses of these routers; let d is the final destination for the packet, and s is the sender's own address. The packet will be allowed to traverse intermediate machines not in the list (that's the difference between "loose source and record route" and "strict source and record route").
A router is, by nature, "between" two (or more) local networks, and has one IP address on each. So the address ik for router k is one of the addresses of the router; the packet sender is expecting the packet to enter that router through the local network which contains ik.
Initially, the source address field is set to s; the destination address field is set to i1; and the loose source and record option contents are set to i1, i2,... in, d. The pointer
field points to i1.
When the packet reaches router 1, the router notices that the destination field address matches one of its own IP. It then does the following: it replaces the destination field address with the next IP in the list (i2) then records its own address in the list: where there was i1, router 1 puts o1. What is o1 ? It is the output address which router 1 will use, that is the address on the other local network on which the packet will next be emitted. It is an address of router 1, just like i1, but on its "other face". The pointer
field is also incremented, so that it now points to the slot containing i2.
The process continues until the last address is reached. Namely, when router n was reached, it wrote d in the destination address field, and wrote on over the value in in the option. When the final destination host is reached, the option contains o1, o2,... on, d. But the source address field (which is not in the option) has remained untouched throughout the whole process; it still contains s, the initial source address.
The idea of source recording is that the destination host could respond to the source host by sending a packet with its own "loose source and record route", and may use the recorded addresses so that the packet follows the same path, in reverse order; the answer packet would initially contain:
- source address field: d
- destination address field: on
- loose source and record route contents: on, on-1,... o1, s
The "output address" of each router is now the "input address", since the answer walks the path in reverse order. And the routers will then put back the
ik addresses on the way back. And so on.
What's the point of this option ? Conceptually, it replaces Network Address Translation; or, more accurately, it implements NAT with the "address translation" using some state information which is in the route option itself.
Imagine that the initial sender A has address 10.0.7.34
(a private address in a local network) and wishes to contact external host B with address 237.23.56.171
. The sender knows an "exit gateway" G which has a private IP (10.0.1.1
) but also an external IP which is "on the Internet" (say, 243.157.4.28
). Thus, the sender uses the loose source and record route option to indicate that the packet should do through 10.0.1.1
. The destination host then receives a packet which comes from 10.0.7.34
(an IP address which makes no sense to the destination host), but which recorded that it went through 243.157.4.28
(that's the address that the "exit gateway" recorded in the option when the packet went through it).
The B host can then respond to A by using the same option, indicating passage through 243.157.4.28
(the external facing address of G). The final destination address for this answer is 10.0.7.34
which has no meaning for B (it is a private address in another network), but the packet will first go to G, and G knows everything about 10.0.7.34
.
That way, millions of machines in a private network could "share" the external address of G, and all be able to contact external servers. One may even do connections between two hosts who are on distinct, private networks, by using source routing through two gateways.
When doing NAT, there must be some state somewhere, which remembers the translation to perform. In NAT as it is commonly used, this state is tables in the router G. G will play with the ports (an UDP/TCP concept) to keep a reference, but the actual state, i.e. the addresses which must be used and replace the ones written in the packets, are in G's RAM. The loose source and record route option allows for putting that state in the packets themselves, thus allowing G to handle millions of combinations without using any RAM at all (and when IPv4 was designed, RAM was very expensive; in 1981, when RFC 791 was written, 64 kB was huge).
However, putting state in packets means that the state could be altered externally. In 1981 everybody on the Internet was cooperating. In 2013, there are bad people. Evil people. Attackers. These people may use the source and record route option to make packets go through unexpected routes and artfully dodge firewalls. It is possible to implement and configure firewalls to inspect and block packets which use the source and record routes, but it requires more thinking. Sysadmins don't like that. They prefer usual NAT where all the state is on their machines, because it makes the problem simpler. So source routing has been deprecated in the 1990s. IPv6 designers tried to revive it, but it is encountering the same lack of support from firewall vendors and sysadmins, who prefer to kill it right away.