Operation of Protocol Independent Multicast, Dense Mode (PIM-DM)

 

As of this writing, no RFC describes PIM-DM. It is, however, described in an Internet draft.[12] Beyond the common message formats, you are likely to find more similarities between PIM-DM and DVMRP than between PIM-DM and PIM-SM.

PIM-DM Basics

PIM-DM uses five PIMv2 messages:

  • Hello

  • Join/Prune

  • Graft

  • Graft-Ack

  • Assert

PIMv2 routers use Hello messages to discover neighbors. When a PIMv2 router (either PIM-DM or PIM-SM) becomes active, it periodically sends a Hello message on every interface on which PIM is configured. PIMv1 routers have the same functionality, except that they use Query messages. The Hello (or Query) messages contain a holdtime, which specifies the maximum time the neighbor should wait to hear a subsequent message before declaring the originating router dead. Both the PIMv2 Hello interval and the PIMv1 Query interval are 30 seconds in Cisco IOS Software by default. They can be changed on a per-interface basis with the command ip pim query-interval. The holdtime is set automatically to 3.5 times the Hello/Query interval.

Example 5-3 shows a debug capture of PIM messages being sent and received. Notice that the router has both PIMv1 and PIMv2 neighbors, as indicated by the Hello and Router-Query keywords. Notice also that the router is sending Hellos on interface E0 but is receiving neither Hellos nor Queries on the interface, indicating that there are no PIM neighbors on that subnet.

Example 5-3 Router Steel Is Querying for Neighbors on Interfaces E0, E1, and S1.708. It Is Hearing from Neighbors on E1 and S1.708
 Steel#  debug ip pim  PIM debugging is on Steel# PIM: Received v2 Hello on Ethernet1 from 172.16.6.3 PIM: Received Router-Query on Serial1.708 from 172.16.2.242 PIM: Send v2 Hello on Ethernet1 PIM: Send v2 Hello on Ethernet0 PIM: Send Router-Query on Serial1.708  (dual PIMv1v2) PIM: Received v2 Hello on Ethernet1 from 172.16.6.3 PIM: Received Router-Query on Serial1.708 from 172.16.2.242 PIM: Send v2 Hello on Ethernet1 PIM: Send v2 Hello on Ethernet0 PIM: Send Router-Query on Serial1.708  (dual PIMv1v2) PIM: Received v2 Hello on Ethernet1 from 172.16.6.3 

In Example 5-4, the debug ip packet detail command is used (linked to an access list to filter uninteresting packets) to get a closer look at the PIM messages. Here, you can see that the PIMv2 messages are sent to 224.0.0.13 and use protocol number 103, whereas the PIMv1 messages are sent to 224.0.0.2 and use protocol number 2.

Example 5-4 This debug Capture Shows the Multicast Destination Addresses and the Protocol Numbers Used by PIMv1 and PIMv2
 Steel#  debug ip packet detail 101  IP packet debugging is on (detailed) for access list 101 Steel# IP: s=172.16.6.3 (Ethernet1), d=224.0.0.13, len 38, rcvd 0, proto=103 IP: s=172.16.2.241 (local), d=224.0.0.2 (Serial1.708), len 35, sending broad/multicast, proto=2 IP: s=172.16.2.242 (Serial1.708), d=224.0.0.2, len 32, rcvd 0, proto=2 IP: s=172.16.6.1 (local), d=224.0.0.13 (Ethernet1), len 30, sending broad/multicast, proto=103 IP: s=172.16.5.1 (local), d=224.0.0.13 (Ethernet0), len 30, sending broad/multicast, proto=103 IP: s=172.16.6.3 (Ethernet1), d=224.0.0.13, len 38, rcvd 0, proto=103 IP: s=172.16.2.241 (local), d=224.0.0.2 (Serial1.708), len 35, sending broad/multicast, proto=2 IP: s=172.16.2.242 (Serial1.708), d=224.0.0.2, len 32, rcvd 0, proto=2 IP: s=172.16.6.1 (local), d=224.0.0.13 (Ethernet1), len 30, sending broad/multicast, proto=103 IP: s=172.16.5.1 (local), d=224.0.0.13 (Ethernet0), len 30, sending broad/multicast, proto=103 

In Example 5-5, the command show ip pim neighbor is used to observe the resulting PIM neighbor table.

Example 5-5 The PIM Neighbor Table Records the Neighbors Heard from in Example 5-3
 Steel#  show ip pim neighbor  PIM Neighbor Table Neighbor Address  Interface          Uptime    Expires   Ver  Mode 172.16.6.3        Ethernet1          01:57:22  00:01:29  v2   Dense  (DR) 172.16.2.242      Serial1.708        04:55:56  00:01:05  v1   Dense Steel# 

When a source begins sending multicast packets, PIM-DM uses flood-and-prune to build the multicast tree. As each PIM-DM router receives a multicast packet, the router adds an entry to its multicast forwarding table. Ultimately, the packets are flooded to all leaf routers ”that is, all routers that have no downstream PIM neighbors. If a leaf router receives a multicast packet for which it has no attached group members, the router must prune itself from the multicast tree. It does this by sending a Prune message to the upstream neighbor toward the source. The destination address of the Prune message is 224.0.0.13, and the address of the upstream router is encoded within the message. If that upstream neighbor has no attached members of the packet's group, and either has no other downstream neighbors or has received prunes from all of its downstream neighbors, it sends a Prune message to its own upstream neighbor toward the source.

Referring back to the bulleted list of PIMv2 message types earlier in this section, you will see that there is no "Prune" message type. Instead, there is a Join/Prune. This is a single message type that has separate fields for listing groups to be joined and groups to be pruned. This section continues to use "Prune message" and "Join message" for clarity, but you should be aware that a Prune message is actually a Join/Prune with a group address listed in the prune section. Likewise, a Join message is a Join/Prune message with a group address in the Join field.

Example 5-6 shows a forwarding table entry for multicast group 239.70.49.238. You can observe the (S, G) pair, showing the source to be 172.16.1.1. The router has consulted its unicast routing table for the upstream interface to the source, which is S1.708, and the upstream neighbor toward the source, which is 172.16.2.242. That information is entered into the multicast forwarding table and is used for the RPF check. As with DVMRP, if a packet with a source address of 172.16.1.1 and a destination address of 239.70.49.238 arrives on any interface other than S1.708, the RPF check fails and the packet is dropped.

NOTE

Example 5-6 does not show all the information in the forwarding table pertaining to this group; some information has been deleted for clarity. Chapter 6 presents the forwarding table in more detail.


Example 5-6 The show ip mroute Command Displays the Multicast Forwarding Table
 Steel#  show ip mroute 239.70.49.238  IP Multicast Routing Table Flags: D - Dense, S - Sparse, C - Connected, L - Local, P - Pruned        R - RP-bit set, F - Register flag, T - SPT-bit set, J - Join SPT Timers: Uptime/Expires Interface state: Interface, Next-Hop or VCD, State/Mode  (172.16.1.1, 239.70.49.238), 01:56:27/00:02:59, flags: CT   Incoming interface: Serial1.708, RPF nbr 172.16.2.242   Outgoing interface list:     Ethernet1, Prune/Dense, 01:40:23/00:00:39     Ethernet0, Forward/Dense, 00:00:46/00:00:00 Steel# 

Associated with the (S, G) entry are two timers. The first timer indicates how long the entry has been in the table. The second timer indicates the expiration time of the entry. If a multicast packet is not forwarded for this (S, G) within 2 minutes and 59 seconds, the entry is deleted.

NOTE

Cisco IOS Software uses an expiration timer of 2.5 minutes, whereas the Internet Draft recommends an expiration timer of 3.5 minutes.


There are also two flags associated with the entry in Example 5-6. The first flag (C) indicates that there is a group member on a directly connected subnet of the router. The second flag (T) indicates that the router is an active member of the shortest path tree (SPT) ”in CBT parlance, it is "on-tree."

NOTE

PIM calls source-based trees shortest path trees, and shared trees rendezvous point trees (RPTs). SPT is a descriptive name , because as you will see in a subsequent section, these trees sometime traverse a shorter path to the source than do the RPTs.


Two interfaces appear on the outgoing interface list in Example 5-6. The first interface, E1, is in prune state and dense mode. Therefore, you know that the downstream neighbor on this interface has sent a Prune message. The timers show that the interface has been up for 1 hour , 40 minutes, and 23 seconds, and that the prune state expires in 39 seconds. When a Prune message is received, a 210-second expiration timer is started. The prune state is maintained until the timer expires, at which time the state is changed to "forward" and packets are again forwarded downstream. It is up to the downstream router to again send a Prune message to its upstream neighbor; this behavior is the same as what you saw for DVMRP.

The second interface, E0, is in forward state. Recall from Example 5-3 that the router is sending Hellos on E0 but is receiving no Hellos from neighbors on that interface. Based on that information and the information in Example 5-6, you know that the router is forwarding on E0 because there is a group member on that subnet. Example 5-7 confirms this conclusion. Notice in Example 5-6 that there is an uptime associated with the interface, but no expiration time. This is because there is no neighbor state to expire. Instead, the router deletes the interface from the forwarding table when IGMP tells it that there are no longer group members on the subnet, or when the expiration timer shown in Example 5-7 reaches 0.

Example 5-7 The show ip igmp group Command Displays the Connected Group Members Recorded in the IGMP Membership Table
 Steel#  show ip igmp group 239.70.49.238  IGMP Connected Group Membership Group Address    Interface            Uptime    Expires   Last Reporter 239.70.49.238    Ethernet0            01:52:23  00:02:34  172.16.5.2 Steel# 

Example 5-8 shows the forwarding table of the next router upstream toward the source. RPF checks are performed for (172.16.1.1, 239.70.49.238) against interface S1.803 and upstream neighbor 172.16.2.254, and there is only one downstream interface. Comparing the flag for this entry against the flags in Example 5-6, you can see that this router is on the shortest path tree but that it has no directly connected group members.

Example 5-8 The Flags for This Entry Indicate That the Router Is on the SPT but That It Has No Directly Connected Group Members
 Nickel#  show ip mroute 239.70.49.238  IP Multicast Routing Table Flags: D - Dense, S - Sparse, C - Connected, L - Local, P - Pruned        R - RP-bit set, F - Register flag, T - SPT-bit set Timers: Uptime/Expires  (172.16.1.1/32, 239.70.49.238), uptime 02:05:23, expires 0:02:58, flags: T   Incoming interface: Serial1.803, RPF neighbor 172.16.2.254   Outgoing interface list:     Serial1.807, Forward state, Dense mode, uptime 02:05:24, expires 0:02:34 Nickel# 

NOTE

The output in Example 5-8 is formatted slightly differently from the preceding forwarding table. This is due to a different Cisco IOS Software Release. However, you can readily see that the information is the same.


Moving upstream again, Example 5-9 shows another forwarding table for the group. The flags again indicate "Connected," but what is connected in this instance is not a group member. Notice that the incoming interface, E0/0, shows an RPF neighbor address of 0.0.0.0. This indicates that the connected device is the source for the group.

Example 5-9 This Router Is Connected to the Source 172.16.1.1, as Indicated by the RPF Neighbor Address of 0.0.0.0
 Bronze#  show ip mroute 239.70.49.238  IP Multicast Routing Table Flags: D - Dense, S - Sparse, C - Connected, L - Local, P - Pruned        R - RP-bit set, F - Register flag, T - SPT-bit set, J - Join SPT Timers: Uptime/Expires Interface state: Interface, Next-Hop, State/Mode  (172.16.1.1/32, 239.70.49.238), 02:10:43/00:02:59, flags: CT   Incoming interface: Ethernet0/0, RPF nbr 0.0.0.0   Outgoing interface list:     Serial0/1.305, Prune/Dense, 02:10:43/00:01:28     Serial0/1.308, Forward/Dense, 02:10:43/00:00:00 Bronze# 

Example 5-9 also shows two outgoing interfaces (172.16.1.1, 239.70.49.238). One is in forwarding state, and the other is in prune state. Like all flood-and-prune protocols, PIM-DM must maintain prune state for all interfaces. The reason for this requirement is so that a router that has pruned itself from a multicast tree can graft itself back onto the tree when necessary.

For example, Example 5-10 shows a router's entry for (172.16.1.1, 239.70.49.238) in which there are no attached group members and no downstream neighbors. As a result, the outgoing interface list is null. The P flag indicates that the router has sent a Prune message to the upstream neighbor 172.16.2.246. If a connected host now sends an IGMP message requesting a join to the group, the router sends a PIM Graft message upstream toward the source. But the only way the router knows the address of the group's source is via the initial flood of multicast packets. Hence, prune state must be maintained as shown in the example.

Example 5-10 This Router Has a Null Outgoing Interface List for the (S,G) Pair (172.16.1.1, 239.70.49.238) and So Has Pruned Itself from That Source Tree
 Lead#  show ip mroute 239.70.49.238  IP Multicast Routing Table Flags: D - Dense, S - Sparse, C - Connected, L - Local, P - Pruned        R - RP-bit set, F - Register flag, T - SPT-bit set Timers: Uptime/Expires Interface state: Interface, Next-Hop, State/Mode  (172.16.1.1/32, 239.70.49.238), 02:32:42/0:00:17, flags: PT   Incoming interface: Serial1.605, RPF nbr 172.16.2.246   Outgoing interface list: Null Lead# 

The Graft message is unicast to the upstream neighbor on the group tree. When the upstream router receives the Graft message, it adds the interface on which the message was received to its outgoing interface list. The interface is put into forward state, and a Graft Ack message is immediately unicast to the new downstream neighbor. If the router is already forwarding packets to other downstream neighbors, nothing else must be done. If the router has also pruned itself from the tree, however, it too must send a Graft to its upstream neighbor. When a router sends a Graft message, it waits 3 seconds for a Graft Ack. If the acknowledgement is not received within that time, the router retransmits the Graft message.

This PIM-DM flood-and-prune mechanism is very similar to that of DVMRP; however, there is one significant difference. Recall from the section "The DVMRP Routing Table" that DVMRP signals route dependencies to upstream neighbors using a poison reverse mechanism. The dependency tells an upstream DVMRP router that a particular downstream router is depending on it to forward packets from a particular source. All this can happen even before the source begins forwarding packets, because of DVMRP's built-in routing protocol. As a result, in some topologies DVMRP can limit the scope of its flooding. PIM-DM does not have this capability, because it does not have a built-in routing protocol. Therefore, PIM-DM always floods to the entire PIM domain. The protocol designers state the following in the specification:

We choose to accept the additional overhead in favor of the simplification and flexibility gained by not depending on a specific type of topology discovery protocol.

Prune Overrides

Another advantage of DVMRP's downstream dependency mechanism is apparent during the prune process. In Figure 5-50, a single router has multiple downstream neighbors. The upstream router, Mercury, is flooding a group's multicast packets onto the LAN connecting the three routers. Copper has a null outgoing interface list and therefore sends a Prune to Mercury. Silver, however, has an attached group member and therefore wants to receive the multicast traffic.

Figure 5-50. Copper Has Sent a Prune Message for (172.16.1.1, 238.70.49.238) Because Its Outgoing Interface List for That (S, G) Pair Is Empty. But Silver Has a Member of the Group and Wants to Continue Receiving the Traffic

graphics/05fig50.gif

If the three routers are running DVMRP, there is no problem. Mercury knows its downstream dependencies for the group's source, and it knows it has received a Prune only from Copper, so it continues to forward traffic for Silver.

Suppose, however, that the routers in Figure 5-50 are running PIM-DM. Mercury certainly knows that it has two neighbors, based on the Hello messages, but nothing in the Hello messages describe dependencies. So when Copper sends a Prune message, Mercury does not know whether or not to prune the LAN interface.

PIM-DM circumvents this problem with a process called prune override. Copper sends the Prune message to Mercury, but Mercury's address is encoded in the message itself. The IP packet carrying the message is addressed to the ALL PIM Routers address 224.0.0.13. When Mercury receives the message, it does not immediately prune the interface. Instead, it sets a 3-second timer. At the same time, Silver also has received the Prune message because of the multicast destination address. It sees that the Prune is for a group it wants to continue receiving, and that the message has been sent to its upstream neighbor forwarding the group traffic. So Silver sends a Join message to Mercury, as illustrated by Figure 5-51. The result is that Silver overrides the Prune sent by Copper. As long as Mercury receives a Join before its 3-second timer expires, no interruption in traffic occurs.

Figure 5-51. Silver Overrides Copper's Prune with a Join Message

graphics/05fig51.gif

Example 5-11 shows a prune override in action. Debugging is used to capture PIM activity on Mercury in Figures 5-50 and 5-51. The first message shows that a Prune (a Join/Prune message with 239.70.49.238 listed in its Prune field) has been received on interface E0 from Copper (172.16.3.2) for the (S, G) pair (172.16.1.1, 239.70.49.238). Notice that the first line indicates that the message is "to us." This is an indicator that Mercury has recognized its own address encoded in the message.

Example 5-11 The Router Mercury in Figure 5-51 Has Received a Prune from Copper (172.16.3.2). Silver (172.16.3.3) Then Sends a Join, Overriding Copper's Prune
 Mercury#  debug ip pim  PIM debugging is on Mercury# PIM: Received Join/Prune on Ethernet0 from 172.16.3.2, to us PIM: Prune-list: (172.16.1.1/32, 239.70.49.238) PIM: Schedule to prune Ethernet0 for (172.16.1.1/32, 239.70.49.238) PIM: Received Join/Prune on Ethernet0 from 172.16.3.3, to us PIM: Join-list: (172.16.1.1/32, 239.70.49.238) PIM: Add Ethernet0/172.16.3.3 to (172.16.1.1/32, 239.70.49.238), Forward state 

The second and third lines show that Mercury has scheduled the (S, G) entry to be pruned from interface E0. That is, the 3-second timer has started. On the fourth line, Mercury has received a Join from Silver (172.16.3.3). On lines 5 and 6, E0 has been put into forward state for the (S, G) pair. Copper's Prune has been overridden.

Unicast Route Changes

When a topology changes, the unicast routing table also changes. And if the unicast route changes affect the route to a source, PIM-DM must also change. An obvious case would be one in which a topology change results in a different previous-hop router on the path to a source.

When a source's RPF router changes, PIM-DM first sends a Prune message to the old router. A Graft message is then sent to the new RPF router to build the new tree.

PIM-DM-Designated Routers

PIM-DM elects a designated router on multiaccess networks. The protocol itself does not need a DR, but recall that IGMPv1 does not have a querier process and relies on the routing protocol to elect a DR to manage IGMP queries. This is the role of the PIM-DM (and PIM-SM) designated router.

The DR election process is quite simple. As you already know, every PIM-DM router sends a PIMv2 Hello message or a PIMv1 Query message every 30 seconds for neighbor discovery. On multiaccess networks, the PIM-DM router with the highest IP address becomes the DR, as illustrated by the output in Example 5-12. The other routers monitor the DR's Hello packets; if none are heard within 105 seconds, the DR is declared dead, and a new DR is elected.

Example 5-12 The PIM Neighbor Table of Mercury in Example 5-11 Indicates That Silver, with the Highest Attached IP Address of 172.16.3.3, Is the Designated Router
 Mercury#  show ip pim neighbor  PIM Neighbor Table Neighbor Address  Interface          Uptime    Expires   Ver  Mode 172.16.3.3        Ethernet0          2d23h     00:01:17  v1v2 Dense    (DR) 172.16.3.2        Ethernet0          2d23h     00:01:21  v1   Dense 172.16.2.250      Serial1.503        09:15:11  00:01:17  v1   Dense Mercury# 

PIM Forwarder Election

In Figure 5-52, both Mercury and Copper have a route to source 172.16.1.1. They also have downstream interfaces to a member of group 239.70.49.238 that are connected to a common multiaccess network. Both Mercury and Copper are receiving copies of the same multicast packets from the source, but it would obviously be inefficient for both routers to forward the packets onto the same network.

Figure 5-52. Both Copper and Mercury Are Receiving Copies of the Multicast Packets Sent by Source 172.16.1.1, but Only One Router Should Forward the Packets onto Subnet 172.16.3.0/24

graphics/05fig52.gif

To prevent such a situation, PIM routers select a single forwarder on the shared network. Recall that DVMRP has a similar function, the designated forwarder. DVMRP-designated forwarders are selected as part of the route exchange across the multiaccess network. Because PIM does not have its own routing protocol, however, it instead uses Assert messages to select the forwarder.

When a router receives a multicast packet on an outgoing multiaccess interface, it sends an Assert message on the network. The Assert message includes the source and group address, the metric of the unicast route to the source, and the metric preference (in Cisco terms, the administrative distance) of the unicast protocol used to discover the route. The routers producing the duplicate packets compare the messages and determine the forwarder based on the following criteria:

  • The router advertising the lowest metric preference (administrative distance) is the forwarder. The routers would advertise only different metric preferences if their routes to the source have been discovered via different unicast routing protocols.

  • If the metric preferences are equal, the router advertising the lowest metric is the forwarder. In other words, if the routers are running the same unicast routing protocol, the router metrically closest to the source becomes the forwarder.

  • If both the metric preferences and the metrics are equal, the forwarder is the router with the highest IP address on the network.

The forwarder continues forwarding group traffic onto the multiaccess network. The other routers stop forwarding that group's traffic and remove the multiaccess interface from their outgoing interface list.

When the multicast source in Figure 5-52 first begins sending packets to group 239.70.49.238, for example, both Copper and Mercury receive copies of the packets, and both routers forward the packets onto subnet 172.16.3.0/24, as illustrated in Part A of Figure 5-53. When Copper receives a packet from Mercury for (172.16.1.1, 239.70.49.238) on its Ethernet interface, it sees that the interface is on the outgoing interface list for that (S, G) pair. As a result, it sends an Assert message on the subnet. When Mercury receives a multicast packet from Copper on the same interface, it takes the same action, as illustrated in Part B of Figure 5-53.

Figure 5-53. When Copper and Mercury Detect Packets for (172.16.1.1, 239.70.49.238) on Their Downstream Multiaccess Interfaces, They Originate Assert Messages to Determine the Forwarder for the Group

graphics/05fig53.gif

Example 5-13 shows Silver's unicast routing table and its multicast forwarding table. The unicast table indicates equal-cost OSPF paths to the source 172.16.1.1 via either Copper (172.16.3.2) or Mercury (172.16.3.1). Because routes are OSPF, they have an equal administrative distance of 110. And because both routes have an OSPF cost of 74, the forwarder is the router with the highest IP address.

Example 5-13 Silver's Unicast Routing Table Shows Two Next-Hop Routers to the Subnet of Source 172.16.1.1. The Multicast Routing Table Shows That the Next-Hop Router with the Highest IP Address Has Been Chosen as the Forwarder
 Silver#  show ip route  Codes: C - connected, S - static, I - IGRP, R - RIP, M - mobile, B - BGP        D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area        N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2        E1 - OSPF external type 1, E2 - OSPF external type 2, E - EGP        i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, * - candidate default        U - per-user static route, o - ODR        T - traffic engineered route Gateway of last resort is not set      172.16.0.0/16 is variably subnetted, 8 subnets, 2 masks O       172.16.2.252/30 [110/138] via 172.16.3.1, 00:02:16, Ethernet1                         [110/138] via 172.16.3.2, 00:02:16, Ethernet1 O       172.16.2.248/30 [110/74] via 172.16.3.1, 00:02:16, Ethernet1 O       172.16.2.244/30 [110/74] via 172.16.3.2, 00:02:16, Ethernet1                         [110/74] via 172.16.3.1, 00:02:16, Ethernet1 O       172.16.2.240/30 [110/138] via 172.16.3.1, 00:02:16, Ethernet1 O       172.16.2.236/30 [110/74] via 172.16.3.1, 00:02:16, Ethernet1 C       172.16.5.0/24 is directly connected, Ethernet0 O       172.16.1.0/24 [110/84] via 172.16.3.1, 00:02:16, Ethernet1                       [110/84] via 172.16.3.2, 00:02:16, Ethernet1 C       172.16.3.0/24 is directly connected, Ethernet1 Silver# Silver#  show ip mroute 172.16.1.1 239.70.49.238  IP Multicast Routing Table Flags: D - Dense, S - Sparse, C - Connected, L - Local, P - Pruned        R - RP-bit set, F - Register flag, T - SPT-bit set, J - Join SPT Timers: Uptime/Expires Interface state: Interface, Next-Hop or VCD, State/Mode (172.16.1.1, 239.70.49.238), 00:02:02/00:02:59, flags: CT   Incoming interface: Ethernet1, RPF nbr 172.16.3.2   Outgoing interface list:     Ethernet0, Forward/Dense, 00:01:50/00:00:00 Silver# 


Routing TCP[s]IP (Vol. 22001)
Routing TCP[s]IP (Vol. 22001)
ISBN: N/A
EAN: N/A
Year: 2004
Pages: 182

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net