SCCS-vsn: sys/netinet/ip_icmp.c 6.2
SCCS-vsn: sys/netinet/icmp_var.h 6.2
-/* icmp_var.h 6.1 83/07/29 */
+/* icmp_var.h 6.2 83/09/19 */
/*
* Variables related to this implementation
/*
* Variables related to this implementation
int icps_oldicmp; /* no error 'cuz old was icmp */
int icps_outhist[ICMP_IREQREPLY + 1];
/* statistics related to input messages processed */
int icps_oldicmp; /* no error 'cuz old was icmp */
int icps_outhist[ICMP_IREQREPLY + 1];
/* statistics related to input messages processed */
+ int icps_badcode; /* icmp_code out of range */
int icps_tooshort; /* packet < ICMP_MINLEN */
int icps_checksum; /* bad checksum */
int icps_badlen; /* calculated bound mismatch */
int icps_tooshort; /* packet < ICMP_MINLEN */
int icps_checksum; /* bad checksum */
int icps_badlen; /* calculated bound mismatch */
-/* ip_icmp.c 6.1 83/07/29 */
+/* ip_icmp.c 6.2 83/09/19 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
#include "../netinet/ip_icmp.h"
#include "../netinet/icmp_var.h"
#include "../netinet/ip_icmp.h"
#include "../netinet/icmp_var.h"
/*
* ICMP routines: error generation, receive packet processing, and
* routines to turnaround packets back to the originator, and
* host table maintenance routines.
*/
int icmpprintfs = 0;
/*
* ICMP routines: error generation, receive packet processing, and
* routines to turnaround packets back to the originator, and
* host table maintenance routines.
*/
int icmpprintfs = 0;
/*
* Generate an error packet of type error
/*
* Generate an error packet of type error
struct mbuf *m;
struct ip *nip;
struct mbuf *m;
struct ip *nip;
if (icmpprintfs)
printf("icmp_error(%x, %d, %d)\n", oip, type, code);
if (icmpprintfs)
printf("icmp_error(%x, %d, %d)\n", oip, type, code);
icmpstat.icps_error++;
/*
* Make sure that the old IP packet had 8 bytes of data to return;
icmpstat.icps_error++;
/*
* Make sure that the old IP packet had 8 bytes of data to return;
-static char icmpmap[] = {
- -1, -1, -1,
- PRC_UNREACH_NET, PRC_QUENCH, PRC_REDIRECT_NET,
- -1, -1, -1,
- -1, -1, PRC_TIMXCEED_INTRANS,
- PRC_PARAMPROB, -1, -1,
- -1, -1
-};
-
static struct sockproto icmproto = { AF_INET, IPPROTO_ICMP };
static struct sockaddr_in icmpsrc = { AF_INET };
static struct sockaddr_in icmpdst = { AF_INET };
static struct sockproto icmproto = { AF_INET, IPPROTO_ICMP };
static struct sockaddr_in icmpsrc = { AF_INET };
static struct sockaddr_in icmpdst = { AF_INET };
* Locate icmp structure in mbuf, and check
* that not corrupted and of at least minimum length.
*/
* Locate icmp structure in mbuf, and check
* that not corrupted and of at least minimum length.
*/
if (icmpprintfs)
printf("icmp_input from %x, len %d\n", ip->ip_src, icmplen);
if (icmpprintfs)
printf("icmp_input from %x, len %d\n", ip->ip_src, icmplen);
if (icmplen < ICMP_MINLEN) {
icmpstat.icps_tooshort++;
goto free;
if (icmplen < ICMP_MINLEN) {
icmpstat.icps_tooshort++;
goto free;
/*
* Message type specific processing.
*/
if (icmpprintfs)
printf("icmp_input, type %d code %d\n", icp->icmp_type,
/*
* Message type specific processing.
*/
if (icmpprintfs)
printf("icmp_input, type %d code %d\n", icp->icmp_type,
+ icp->icmp_code);
+#endif
if (icp->icmp_type > ICMP_IREQREPLY)
goto free;
icmpstat.icps_inhist[icp->icmp_type]++;
if (icp->icmp_type > ICMP_IREQREPLY)
goto free;
icmpstat.icps_inhist[icp->icmp_type]++;
switch (icp->icmp_type) {
case ICMP_UNREACH:
switch (icp->icmp_type) {
case ICMP_UNREACH:
+ if (code > 5)
+ goto badcode;
+ code += PRC_UNREACH_NET;
+ goto deliver;
+
+ if (code > 1)
+ goto badcode;
+ code += PRC_TIMXCEED_INTRANS;
+ goto deliver;
+
+ if (code)
+ goto badcode;
+ code = PRC_PARAMPROB;
+ goto deliver;
+
+ if (code)
+ goto badcode;
+ code = PRC_QUENCH;
+ deliver:
- * Problem with previous datagram; advise
- * higher level routines.
+ * Problem with datagram; advise higher level routines.
*/
icp->icmp_ip.ip_len = ntohs((u_short)icp->icmp_ip.ip_len);
if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp)) {
icmpstat.icps_badlen++;
goto free;
}
*/
icp->icmp_ip.ip_len = ntohs((u_short)icp->icmp_ip.ip_len);
if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp)) {
icmpstat.icps_badlen++;
goto free;
}
if (icmpprintfs)
printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
if (icmpprintfs)
printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
- code = icp->icmp_type == ICMP_PARAMPROB ? 0 : icp->icmp_code;
if (ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput)
if (ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput)
- (*ctlfunc)(icmpmap[icp->icmp_type]+code, (caddr_t)icp);
+ (*ctlfunc)(code, (caddr_t)icp);
+ goto free;
+
+ badcode:
+ icmpstat.icps_badcode++;
goto free;
case ICMP_ECHO:
goto free;
case ICMP_ECHO:
goto reflect;
case ICMP_IREQ:
goto reflect;
case ICMP_IREQ:
/* fill in source address zero fields! */
goto reflect;
/* fill in source address zero fields! */
goto reflect;
+#else
+ goto free; /* not yet implemented: ignore */
+#endif
case ICMP_REDIRECT:
case ICMP_ECHOREPLY:
case ICMP_REDIRECT:
case ICMP_ECHOREPLY:
icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen);
m->m_off -= hlen;
m->m_len += hlen;
icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen);
m->m_off -= hlen;
m->m_len += hlen;
if (icmpprintfs)
printf("icmp_send dst %x src %x\n", ip->ip_dst, ip->ip_src);
if (icmpprintfs)
printf("icmp_send dst %x src %x\n", ip->ip_dst, ip->ip_src);
(void) ip_output(m, (struct mbuf *)0, (struct route *)0, 0);
}
(void) ip_output(m, (struct mbuf *)0, (struct route *)0, 0);
}