You probably aren't going to log every packet that is allowed, but you might want to log some of these packets. For example, you might want to log start-of-connection TCP packets, so that you can keep track of incoming and outgoing TCP connections. Not all packet filters will log allowed packets.
Different packet filtering implementations support different forms of logging. Some will log only specific information about a packet, and others will forward or log an entire dropped packet. Generally, your packet filter will need to be configured to log to a host somewhere via the syslog service. You don't want the only copy of the logs to be on the packet filter if it is compromised. Most packet filtering also occurs on dedicated routers, which rarely have large amounts of disk space to dedicate to logging. See the discussion of setting up logging in Chapter 10, "Bastion Hosts", and Chapter 26, "Maintaining Firewalls".
There are two sets of relevant ICMP codes to choose from:
The second set of ICMP error codes the router might return, "host administratively unreachable" and "network administratively unreachable", were added to the official list of ICMP message types later, specifically to give packet filtering systems something to return when they dropped a packet. Even though they're in the standard, they're not implemented everywhere. Theoretically, this is not a problem; the RFCs specify that a host that gets an ICMP code it doesn't understand should simply ignore the packet. In practice, not all systems will handle this gracefully. The best the standard can do for you is ensure that it is officially not your fault if somebody else's system crashes when you send it an ICMP packet it doesn't understand.
There are several issues to consider when you are deciding whether or not your packet filtering system should return ICMP error codes:
Will returning these codes enable attackers to get too much information about your packet filtering?
Returning the new "host administratively unreachable" or "network administratively unreachable" codes advertises the fact that there is a packet filtering system at your site, which you may or may not want to do. These codes may also cause excessive reactions in faulty IP implementations.
There is another consideration as well. Generating and returning ICMP error codes takes a certain small amount of effort on the part of the packet filtering router. An attacker could conceivably mount a denial of service attack by flooding the router with packets the router would reject and for which it would try to generate ICMP error packets. The issue isn't network bandwidth; it's CPU load on the router. (While it's busy generating ICMP packets, it's not able to do other things as quickly, like make filtering decisions.) On the other hand, not returning ICMP error codes will cause a small amount of excess network traffic, as the sending system tries and retries to send the packet being dropped. This traffic shouldn't amount to much, because the number of packets blocked by a packet filtering system should be a fraction of the total number of packets processed. (If it's not a small fraction, you've got more serious problems because people are apparently trying lots of things that "aren't allowed".)
If your router returns an ICMP error code for every packet that violates your filtering policy, you're also giving an attacker a way to probe your filtering system. By observing which packets evoke an ICMP error response, attackers can discover what types of packets do and don't violate your policy (and thus what types of packets are and are not allowed into your network). You should not give this information away because it greatly simplifies the attacker's job. The attacker knows that packets that don't get the ICMP error are going somewhere and can concentrate on those protocols where you actually have vulnerabilities. You'd rather that the attacker spent plenty of time sending you packets that you happily throw away. Returning ICMP error codes speeds up attack programs; if they get back an ICMP error for something they try, they don't have to wait for a timeout.
All in all, the safest thing to do seems to be to drop packets without returning any ICMP error codes. If your router offers enough flexibility, it might make sense to configure it to return ICMP error codes to internal systems (which would like to know immediately that something is going to fail, rather than wait for a timeout) but not to external systems (where the information would give an attacker a means to probe the filtering configuration of the firewall). Even if your router doesn't seem to offer such flexibility, you may be able to accomplish the same result by specifying packet filtering rules to allow the relevant inbound ICMP packets and disallow the relevant outbound ICMP packets.
Some packet filtering systems also allow you to shut off TCP connections without using ICMP, by responding with a TCP reset, which aborts the connection. This is the response that a machine would normally give if it received a TCP packet bound for a port where nothing was listening. Although TCP resets give away less information than ICMP error codes, they still speed up attack programs.
There is one case where you do not usually want to drop packets without an error. A number of systems use the authorization service implemented by identd to attempt to do user authentication on incoming connections (usually on mail and IRC connections). If you are not running identd or another server that provides information via the Auth protocol, it is advisable to return errors on these attempts, in order to speed up mail delivery to systems using this kind of authorization. If you drop packets without errors, the other system will have to wait for its request to time out before continuing the process of accepting the mail. This can significantly increase the load on your mail system if you need to deliver large amounts of mail. Auth and identd are discussed further in Section 21.1, "What Is Authentication?".
A packet filter can change the destination of the packet either by changing the destination information in the packet (for instance, as part of network address translation or load balancing between servers), or by encapsulating the packet inside another one (this allows a packet filtering router to cooperate with another machine to provide transparent proxying).
When a stateful packet filter gets a packet, it decides not only whether to forward or drop the packet, but also whether to modify its state based on the packet. For instance, if the packet is an outbound UDP packet, the packet filter may change state to allow inbound packets that appear to be replies. If the packet is the first packet in a TCP connection (it has the SYN bit set but no ACK, see Section 4.1, "What Does a Packet Look Like?", for more details), the packet filter may change state to expect a packet with both the SYN bit and the ACK bit set. When it gets that second packet, it will then change state to expect packets with the ACK bit but not the SYN bit set. This enforces a correct TCP handshake, getting rid of some attacks involving interesting settings of header bits.
Some packet filtering systems will also modify parts of packets besides the destination. This is the basis of packet filtering systems that provide network address translation; they need to modify not only destination information, but also source information and sometimes embedded IP addresses further into the packet.