Les messages ICMP sont utilisés pour les types d'erreurs basiques rapportées entre hôtes, ou entre hôte et passerelle. Entre passerelles, un protocole appelé GGP (Gateway to gateway protocol) ou passerelle à passerelle doit normalement être utilisé pour le rapport d'erreur. Comme nous l'avons déjà vu, le protocole IP n'a pas été conçu pour parfaire le maniement d'erreur, mais les messages ICMP résolvent une partie de ces problèmes. Le gros problème de ce point de vue est que les en-têtes des messages ICMP sont plutôt compliqués, et diffèrent de message en message. Cependant, ce n'est pas une grosse difficulté du point de vue filtrage la plupart du temps.
La forme de base du message contient l'en-tête IP standard, le type, le code et la somme de contrôle. Tous les messages ICMP contiennent ces champs. Le type spécifie le genre d'erreur du message de réponse, comme par exemple, destination injoignable, écho, réponse d'écho, ou message redirigé. Le code donne plus d'information si nécessaire. Si le paquet est de type destination injoignable, il y a plusieurs valeurs possibles comme réseau injoignable, hôte injoignable, ou port injoignable. La somme de contrôle est simplement une somme pour l'ensemble du paquet.
Comme vous avez pû le noter, j'ai mentionné explicitement l'en-tête IP pour le paquet ICMP. C'est dû au fait que l'en-tête IP actuel est une partie intégrale du paquet ICMP, et que le protocole ICMP est au même niveau, dans un sens, que le protocole IP. ICMP utilise le protocole IP comme s'il était à un niveau plus haut, mais en même temps ce n'est pas le cas. ICMP est une partie intégrale de IP, et ICMP doit être présent dans chaque implémentation de IP.