|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2009 Michael Brown <[email protected]>. ! 3: * ! 4: * This program is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2 of the ! 7: * License, or any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, but ! 10: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 12: * General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with this program; if not, write to the Free Software ! 16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 17: */ ! 18: ! 19: FILE_LICENCE ( GPL2_OR_LATER ); ! 20: ! 21: #include <string.h> ! 22: #include <errno.h> ! 23: #include <ipxe/iobuf.h> ! 24: #include <ipxe/in.h> ! 25: #include <ipxe/tcpip.h> ! 26: #include <ipxe/icmp.h> ! 27: ! 28: /** @file ! 29: * ! 30: * ICMP protocol ! 31: * ! 32: */ ! 33: ! 34: struct tcpip_protocol icmp_protocol __tcpip_protocol; ! 35: ! 36: /** ! 37: * Process a received packet ! 38: * ! 39: * @v iobuf I/O buffer ! 40: * @v st_src Partially-filled source address ! 41: * @v st_dest Partially-filled destination address ! 42: * @v pshdr_csum Pseudo-header checksum ! 43: * @ret rc Return status code ! 44: */ ! 45: static int icmp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, ! 46: struct sockaddr_tcpip *st_dest, ! 47: uint16_t pshdr_csum __unused ) { ! 48: struct icmp_header *icmp = iobuf->data; ! 49: size_t len = iob_len ( iobuf ); ! 50: unsigned int csum; ! 51: int rc; ! 52: ! 53: /* Sanity check */ ! 54: if ( len < sizeof ( *icmp ) ) { ! 55: DBG ( "ICMP packet too short at %zd bytes (min %zd bytes)\n", ! 56: len, sizeof ( *icmp ) ); ! 57: rc = -EINVAL; ! 58: goto done; ! 59: } ! 60: ! 61: /* Verify checksum */ ! 62: csum = tcpip_chksum ( icmp, len ); ! 63: if ( csum != 0 ) { ! 64: DBG ( "ICMP checksum incorrect (is %04x, should be 0000)\n", ! 65: csum ); ! 66: DBG_HD ( icmp, len ); ! 67: rc = -EINVAL; ! 68: goto done; ! 69: } ! 70: ! 71: /* We respond only to pings */ ! 72: if ( icmp->type != ICMP_ECHO_REQUEST ) { ! 73: DBG ( "ICMP ignoring type %d\n", icmp->type ); ! 74: rc = 0; ! 75: goto done; ! 76: } ! 77: ! 78: DBG ( "ICMP responding to ping\n" ); ! 79: ! 80: /* Change type to response and recalculate checksum */ ! 81: icmp->type = ICMP_ECHO_RESPONSE; ! 82: icmp->chksum = 0; ! 83: icmp->chksum = tcpip_chksum ( icmp, len ); ! 84: ! 85: /* Transmit the response */ ! 86: if ( ( rc = tcpip_tx ( iob_disown ( iobuf ), &icmp_protocol, st_dest, ! 87: st_src, NULL, NULL ) ) != 0 ) { ! 88: DBG ( "ICMP could not transmit ping response: %s\n", ! 89: strerror ( rc ) ); ! 90: goto done; ! 91: } ! 92: ! 93: done: ! 94: free_iob ( iobuf ); ! 95: return rc; ! 96: } ! 97: ! 98: /** ICMP TCP/IP protocol */ ! 99: struct tcpip_protocol icmp_protocol __tcpip_protocol = { ! 100: .name = "ICMP", ! 101: .rx = icmp_rx, ! 102: .tcpip_proto = IP_ICMP, ! 103: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.