50 void (*handler) (
struct iaddr, u_int8_t *,
int);
52 struct protoent *proto;
59 log_fatal (
"attempted to reinitialize icmp protocol");
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 sizeof (
struct icmp_state),
66 if (result != ISC_R_SUCCESS)
67 log_fatal (
"Can't register icmp object type: %s",
68 isc_result_totext (result));
70 icmp_state_allocate (&icmp_state,
MDL);
71 icmp_state -> icmp_handler = handler;
86 proto = getprotobyname (
"icmp");
88 protocol = proto -> p_proto;
91 icmp_state -> socket = socket (AF_INET, SOCK_RAW, protocol);
92 if (icmp_state -> socket < 0) {
94 log_error (
"unable to create icmp socket: %m");
98 #if defined (HAVE_SETFD) 99 if (fcntl (icmp_state -> socket, F_SETFD, 1) < 0)
100 log_error (
"Can't set close-on-exec on icmp: %m");
105 if (setsockopt (icmp_state -> socket, SOL_SOCKET, SO_DONTROUTE,
106 (
char *)&state,
sizeof state) < 0)
107 log_fatal (
"Can't disable SO_DONTROUTE on ICMP: %m");
112 if (result != ISC_R_SUCCESS)
113 log_fatal (
"Can't register icmp handle: %s",
114 isc_result_totext (result));
115 #if defined (TRACING) 123 struct icmp_state *state;
125 state = (
struct icmp_state *)h;
132 struct sockaddr_in to;
135 #if defined (TRACING) 142 log_fatal (
"ICMP protocol used before initialization.");
144 memset (&to, 0,
sizeof(to));
146 to.sin_len =
sizeof to;
148 to.sin_family = AF_INET;
150 memcpy (&to.sin_addr, addr -> iabuf,
sizeof to.sin_addr);
156 #if SIZEOF_STRUCT_IADDR_P == 8 157 icmp.icmp_id = (((u_int32_t)(u_int64_t)addr) ^
158 (u_int32_t)(((u_int64_t)addr) >> 32));
160 icmp.icmp_id = (u_int32_t)addr;
167 #if defined (TRACING) 169 char *buf = (
char *)0;
174 if (status != ISC_R_SUCCESS)
176 isc_result_totext (status));
181 iov [0].
buf = (
char *)addr;
182 iov [0].
len =
sizeof *addr;
183 iov [1].
buf = (
char *)&icmp;
184 iov [1].
len =
sizeof icmp;
190 status = sendto (icmp_state -> socket,
191 (
char *)&icmp,
sizeof icmp, 0,
192 (
struct sockaddr *)&to,
sizeof to);
195 inet_ntoa(to.sin_addr));
197 if (status !=
sizeof icmp)
199 #if defined (TRACING) 210 struct sockaddr_in from;
211 u_int8_t icbuf [1500];
216 struct icmp_state *state;
217 #if defined (TRACING) 221 state = (
struct icmp_state *)h;
224 status = recvfrom (state ->
socket, (
char *)icbuf,
sizeof icbuf, 0,
225 (
struct sockaddr *)&from, &sl);
228 return ISC_R_UNEXPECTED;
232 ip = (
struct ip *)icbuf;
236 if (status < hlen + (
sizeof *icfrom)) {
237 return ISC_R_SUCCESS;
241 icfrom = (
struct icmp *)(icbuf + hlen);
245 return ISC_R_SUCCESS;
249 if (state -> icmp_handler) {
250 memcpy (ia.
iabuf, &from.sin_addr,
sizeof from.sin_addr);
251 ia.
len =
sizeof from.sin_addr;
253 #if defined (TRACING) 256 iov [0].
buf = (
char *)&ia;
257 iov [0].
len =
sizeof ia;
258 iov [1].
buf = (
char *)icbuf;
264 (*state -> icmp_handler) (ia, icbuf, len);
266 return ISC_R_SUCCESS;
269 #if defined (TRACING) 274 ia = (
struct iaddr *)buf;
276 icbuf = (u_int8_t *)(ia + 1);
277 if (icmp_state -> icmp_handler)
278 (*icmp_state -> icmp_handler) (*ia, icbuf,
279 (
int)(length -
sizeof ia));
288 if (length != (
sizeof (
struct icmp) +
sizeof (ia))) {
289 log_error (
"trace_icmp_output_input: data size mismatch %d:%d",
290 length, (
int)(
sizeof (
struct icmp) +
sizeof (ia)));
294 memcpy (ia.
iabuf, buf, 4);
isc_result_t omapi_register_io_object(omapi_object_t *, int(*)(omapi_object_t *), int(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *))
const char * piaddr(const struct iaddr addr)
void trace_icmp_output_input(trace_type_t *, unsigned, char *)
void icmp_startup(int routep, void *handler)
void trace_icmp_input_stop(trace_type_t *)
isc_result_t trace_write_packet_iov(trace_type_t *, int, trace_iov_t *, const char *, int)
void trace_icmp_input_input(trace_type_t *, unsigned, char *)
int log_error(const char *,...) __attribute__((__format__(__printf__
trace_type_t * trace_type_register(const char *, void *, void(*)(trace_type_t *, unsigned, char *), void(*)(trace_type_t *), const char *, int)
#define OMAPI_OBJECT_ALLOC(name, stype, type)
struct icmp_state * icmp_state
u_int32_t wrapsum(u_int32_t sum)
void log_fatal(const char *,...) __attribute__((__format__(__printf__
void trace_icmp_output_stop(trace_type_t *)
void dfree(void *, const char *, int)
isc_result_t omapi_object_type_register(omapi_object_type_t **, const char *, isc_result_t(*)(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *), isc_result_t(*)(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **), isc_result_t(*)(omapi_object_t *, const char *, int), isc_result_t(*)(omapi_object_t *, const char *, va_list), isc_result_t(*)(omapi_object_t *, omapi_object_t *, omapi_object_t *), isc_result_t(*)(omapi_object_t **, omapi_object_t *, omapi_object_t *), isc_result_t(*)(omapi_object_t **, omapi_object_t *), isc_result_t(*)(omapi_object_t *, omapi_object_t *), isc_result_t(*)(omapi_object_t *, const char *, int), isc_result_t(*)(omapi_object_t **, const char *, int), isc_result_t(*)(size_t), size_t, isc_result_t(*)(omapi_object_t *, const char *, int), int)
isc_result_t trace_get_packet(trace_type_t **, unsigned *, char **)
int icmp_readsocket(omapi_object_t *h)
isc_result_t icmp_echoreply(omapi_object_t *h)
int icmp_echorequest(struct iaddr *addr)
u_int32_t checksum(unsigned char *buf, unsigned nbytes, u_int32_t sum)