icmp.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <string.h>
00022 #include <errno.h>
00023 #include <gpxe/iobuf.h>
00024 #include <gpxe/in.h>
00025 #include <gpxe/tcpip.h>
00026 #include <gpxe/icmp.h>
00027
00028
00029
00030
00031
00032
00033
00034 struct tcpip_protocol icmp_protocol __tcpip_protocol;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 static int icmp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src,
00046 struct sockaddr_tcpip *st_dest,
00047 uint16_t pshdr_csum __unused ) {
00048 struct icmp_header *icmp = iobuf->data;
00049 size_t len = iob_len ( iobuf );
00050 unsigned int csum;
00051 int rc;
00052
00053
00054 if ( len < sizeof ( *icmp ) ) {
00055 DBG ( "ICMP packet too short at %zd bytes (min %zd bytes)\n",
00056 len, sizeof ( *icmp ) );
00057 rc = -EINVAL;
00058 goto done;
00059 }
00060
00061
00062 csum = tcpip_chksum ( icmp, len );
00063 if ( csum != 0 ) {
00064 DBG ( "ICMP checksum incorrect (is %04x, should be 0000)\n",
00065 csum );
00066 DBG_HD ( icmp, len );
00067 rc = -EINVAL;
00068 goto done;
00069 }
00070
00071
00072 if ( icmp->type != ICMP_ECHO_REQUEST ) {
00073 DBG ( "ICMP ignoring type %d\n", icmp->type );
00074 rc = 0;
00075 goto done;
00076 }
00077
00078 DBG ( "ICMP responding to ping\n" );
00079
00080
00081 icmp->type = ICMP_ECHO_RESPONSE;
00082 icmp->chksum = 0;
00083 icmp->chksum = tcpip_chksum ( icmp, len );
00084
00085
00086 if ( ( rc = tcpip_tx ( iob_disown ( iobuf ), &icmp_protocol, st_dest,
00087 st_src, NULL, NULL ) ) != 0 ) {
00088 DBG ( "ICMP could not transmit ping response: %s\n",
00089 strerror ( rc ) );
00090 goto done;
00091 }
00092
00093 done:
00094 free_iob ( iobuf );
00095 return rc;
00096 }
00097
00098
00099 struct tcpip_protocol icmp_protocol __tcpip_protocol = {
00100 .name = "ICMP",
00101 .rx = icmp_rx,
00102 .tcpip_proto = IP_ICMP,
00103 };