4.3. PPPoEThe IP-in-IP tunnel that we studied in the previous section was an example of a network-layer protocol encapsulating another network-layer protocolindeed, the same network-layer protocol. In this section, we look at an example of tunneling an interface protocol in another interface protocol. Digital Subscriber Line (DSL) providers use the PPP over Ethernet (PPPoE) protocol to tunnel PPP over Ethernet links. DSL modems are essentially simple Ethernet bridges that connect a remote site with access multiplexers (DSLAMs) at the telco central office, as shown in Figure 4.7. In order to manage DSL accounts and leverage their existing technology, ISPs often tunnel PPP over this Ethernet link. Figure 4.7. Typical DSL Infrastructure
The PPPoE protocol itself has two stages. In the first stage, PPPoE discovery, the clienta host or gateway on the customer's LANdiscovers the Ethernet MAC address of an access multiplexer willing to provide it service, and sets up the PPPoE tunnel. In the second stage, the PPP session, the client and DSLAM send normal PPP traffic through the tunnel. Figure 4.8 shows the data flow for a typical PPPoE session. During the discovery stage, the Ethernet frames carry discovery packets that consist of a PPPoE header (Figure 4.10) and a payload for negotiating tunnel parameters. The Ethernet protocol field (ETHER_TYPE) is set to 0x8863 for these packets. The parameters are encoded tag-length-value triplets called TAGs. TAGs have the format shown in Figure 4.9. The type field identifies the type of tag, and the length field specifies the length in bytes of the value field that contains the TAG's value. Figure 4.8. A Typical PPPoE Session
Figure 4.9. A PPPoE TAGThe client first broadcasts a PPPoE active discovery initiation (PADI) packet. This packet specifies the service that the client is requestinga particular ISP, for exampleand any server willing to provide that service responds with a PPPoE active discovery offer (PADO) packet. The PADO packet contains the server's name, the service that the PADI packet specified, and any other services that the server can provide. The client chooses one of the servers that responded with a PADO packet and sends it a PPPoE active discovery request (PADR) packet, again specifying the service it is seeking. If the service is acceptable to the server, it responds with a PPPoE active discovery session-confirmation (PADS) packet. The PADS packet specifies the service name that the client and server have agreed upon, and also sets the session ID. At this point, the tunnel is established, and PPP can begin its LCP phase, as described in Chapter 2. When the client and server are finished with the tunnel, one side sends a PPPoE active discovery terminate (PADT) packet. This packet terminates the PPPoE session, and the tunnel is torn down. Although not a product of the IETF, the PPPoE specification is documented in RFC 2516 [Mamakos, Lidl, Evarts, Carrel, Simone, and Wheeler 1999]. In addition to describing the discovery stage as we have here, the RFC describes the type and values of the TAGs used as discovery parameters. The PPPoE header is shown in Figure 4.10. The ver and type fields are both set to 0x1. Figure 4.10. The PPPoE Header
The code field indicates the type of payload the PPPoE packet is carrying. These packet types are listed in Figure 4.11.
The session ID field contains a unique identifier that identifies the session. This field is set to 0 for the PADI, PADO, and PADR packets. The PPPoE server specifies the session ID in the PADS packet, and all packets for the remainder of the session must set the session ID to the same value. The length field is the size in bytes of the packet payload. The length does not include the Ethernet or PPPoE headers. The PPPoE encapsulation during the PPP session stage is shown in Figure 4.12. Figure 4.12. PPPoE EncapsulationThe Ethernet frame type is set to 0x8864 during the PPP session stage. To see PPPoE in action, let's set up a PPPoE server on bsd and a PPPoE client on linux. We start the server on bsd with bsd# /usr/libexec/pppoed -l pppoed -p pppoe dc1The -p pppoe says that we will provide a service named pppoe, and the dc1 indicates that the server will listen for connections on the dc1 interface. The -l pppoed is the ppp.conf file label that specifies the parameters for the resulting PPP session when a client connects (Figure 4.13). Figure 4.13. Part of the PPP Configuration File
Most of these parameters simply set the default values for a PPPoE session. Lines 2627 disable address and control field compression, protocol field compression, and PPP payload compression. We turned off PPP payload compression in order to see the encapsulation when we watch the traffic with tcpdump. We disabled the other two compressions because the PPPoE specification either requires itaddress and control field compressionor recommends itprotocol field compression. The last line sets the IP addresses for the session. The server will have the address 10.0.0.1, and the client will have the address 10.0.0.2. On linux, we start the PPPoE client with linux:/home/jcs # pppd pty 'pppoe -I eth1 -S pppoe'This line tells the PPP daemon, pppd, to run pppoe and communicate through it rather than a serial device. The -I eth1 in the pppoe call says to use the eth1 interface to locate a server, and the -S pppoe says to ask for service pppoe. We run tcpdump on the dc1 interface of bsd to watch the traffic. First, linux looks for a PPPoE server by broadcasting a PADI packet: 1 16:58:55.686210 PPPoE PADI [Service-Name "pppoe"] 2 16:58:55.687648 PPPoE PADO [AC-Name "bsd"] [Service-Name "pppoe"] [AC-Cookie UTF8] 3 16:58:55.691609 PPPoE PADR [Service-Name "pppoe"] [AC-Cookie UTF8] 4 16:58:55.691630 PPPoE PADS [ses 0xb] [AC-Name "bsd"] [Service-Name "pppoe"] [AC-Cookie UTF8] As expected from the -S pppoe in its invocation, the PPPoE client is looking for service pppoe. On line 2, the server on bsd responds with a PADO packet offering to provide the pppoe service. Line 2 also gives the name of the server as bsdthe AC stands for access concentrator, another name for a DSLAMand sends a cookie that it uses to help prevent denial-of-service attacks. The client accepts the offer on line 3 with its PADR packet. Notice that the client again specifies the service name it wants, because the server could have offered more than one service. The client also returns the cookie that the server sent in the PADO packet. Finally, the server confirms the session on line 4 with its PADS packet. Notice that the server specifies the session ID as 0xb. At this point, the PPPoE session has been established, and the PPP negotiations can begin: 5 16:58:56.673573 PPPoE [ses 0xb] Conf-Req(1), ACCM=00000000, Magic-Num=4fef4ea8, PFC, ACFC 6 16:58:56.674455 PPPoE [ses 0xb] Conf-Req(1), MRU=1492, Magic-Num=2f01f605 19 lines of PPP negotiation deleted 26 16:58:56.680379 PPPoE [ses 0xb] Conf-Ack(3), IP-Addr=10.0.0.2 Once the PPP session is established, we ping 10.0.0.2 from 10.0.0.1. This time, we ask tcpdump to show us the whole packet so that we can see the encapsulation: 27 16:59:05.206220 PPPoE [ses 0xb] 10.0.0.1 > 10.0.0.2: icmp: echo request 27.1 1100 000b 0056 0021 4500 0054 0a18 0000 .....V.!E..T.... 27.2 4001 5c8f 0a00 0001 0a00 0002 0800 f44b @.............K 27.3 4f02 0000 994a 5a3f d324 0300 0809 0a0b O....JZ?.$...... 27.4 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b ................ 27.5 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b .....!"#$%&'()*+ 27.6 2c2d 2e2f 3031 3233 3435 3637 ,-./01234567 The PPPoE header is set in boldface on line 27.1. As expected, the ver and type fields are both set to 0x1. The code is 0, indicating that this packet is carrying PPP session data (Figure 4.11). The length field is set to 86 (0x56), which is the default ping packet size of 84 plus two more for the PPP protocol field of 0x0021: 27.1 1100 000b 0056 0021 4500 0054 0a18 0000 .....V.!E..T.... Recall that a protocol of 0x0021 indicates that the PPP packet is carrying an IP datagram. The rest of the packet is a normal ping packet, which we examined in Chapter 2. There is no HDLC framing: The address, control, and FCS fields are omitted. The first PPP field is the protocol field as shown in line 27.1. After we finish with the ping, we shut down the PPPoE client on linux: 33 16:59:22.666941 PPPoE [ses 0xb] Term-Req(3) 34 16:59:22.668703 PPPoE [ses 0xb] Term-Ack(3) 35 16:59:22.740762 PPPoE PADT [ses 0xb] [Generic-Error "RP-PPPoE: System call error: Input/output error"] [AC-Cookie UTF8] 36 16:59:22.740799 PPPoE PADT [ses 0xb] [Generic-Error "session closed"] The client sends a PPP session-terminate request, which the server ACKs, and then both sides send a PADT, which tears down the tunnel. Many authorities believe that the PPPoE protocol has serious deficiencies involving robustness and securitysee [Carlson 2000] for a good summary of the typical complaintsand that in any event, its functions could be better handled by using existing protocols. Nevertheless, its use by DSL providers means that it's ubiquitous, and that implementers and system administrators will have to understand and deal with it. |