d5a0b3f21b9929b1d873bb5c5e0c560c181b8c8b
/* ip_icmp.c 4.12 82/01/19 */
#include "../h/protosw.h"
#include "../net/in_systm.h"
#include "../net/ip_icmp.h"
* ICMP routines: error generation, receive packet processing, and
* routines to turnaround packets back to the originator, and
* host table maintenance routines.
* Generate an error packet of type error in response to bad packet ip.
icmp_error(oip
, type
, code
)
unsigned oiplen
= oip
->ip_hl
<< 2;
struct icmp
*icp
= (struct icmp
*)((int)oip
+ oiplen
);
* Make sure that the old IP packet had 8 bytes of data to return;
* if not, don't bother. Also don't EVER error if the old
* packet protocol was ICMP.
if (oip
->ip_len
- oiplen
< 8 || oip
->ip_p
== IPPROTO_ICMP
)
* Get a new mbuf, and fill in a ICMP header at the bottom
* of the mbuf, followed by the old IP header and 8 bytes
m
->m_off
= MMAXOFF
- (oiplen
+ 8);
if (type
== ICMP_PARAMPROB
) {
bcopy((caddr_t
)oip
, (caddr_t
)&icp
->icmp_ip
, oiplen
+ 8);
* Now prepend an IP header and reflect this packet back to
m
->m_off
-= sizeof (struct ip
);
m
->m_len
+= sizeof (struct ip
);
nip
= (struct ip
*)mtod(m
, struct ip
*);
* Discard mbufs of original datagram
* Process a received ICMP message.
register struct icmp
*icp
;
register struct ip
*ip
= mtod(m
, struct ip
*);
int hlen
= ip
->ip_hl
<< 2;
int icmplen
= ip
->ip_len
- hlen
;
extern u_char ip_protox
[];
* Locate icmp structure in mbuf, and check
* that not corrupted and of at least minimum length.
/* need routine to make sure header is in this mbuf here */
icp
= (struct icmp
*)mtod(m
, struct icmp
*);
if (i
!= in_cksum(m
, icmplen
) || icmplen
< ICMP_MINLEN
)
* Message type specific processing.
switch (icp
->icmp_type
) {
* Problem with previous datagram; advise
if (icmplen
< ICMP_ADVLENMIN
|| icmplen
< ICMP_ADVLEN(icp
))
(*protosw
[ip_protox
[ip
->ip_p
]].pr_ctlinput
)(m
);
icp
->icmp_type
= ICMP_ECHOREPLY
;
if (icmplen
< ICMP_TSLEN
)
icp
->icmp_type
= ICMP_TSTAMPREPLY
;
icp
->icmp_rtime
= iptime();
icp
->icmp_ttime
= icp
->icmp_rtime
; /* bogus, do later! */
/* fill in source address zero fields! */
if (icmplen
< ICMP_ADVLENMIN
|| icmplen
< ICMP_ADVLEN(icp
))
* Reflect the ip packet back to the source
t
= ip
->ip_src
; ip
->ip_dst
= ip
->ip_src
; ip
->ip_src
= t
;
* This is a little naive... do we have to munge the options
* to reverse source routing?
* Send an icmp packet back to the ip level, after
* Got a reply, e.g. to an echo message or a timestamp
* message; nothing is done with these yet.
t
= (time
% SECDAY
) * 1000 + lbolt
* hz
;