From owner-p4-projects@FreeBSD.ORG Thu Apr 26 16:02:36 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8B54716A409; Thu, 26 Apr 2007 16:02:36 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 26F9116A402 for ; Thu, 26 Apr 2007 16:02:36 +0000 (UTC) (envelope-from taleks@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 1587813C46A for ; Thu, 26 Apr 2007 16:02:36 +0000 (UTC) (envelope-from taleks@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l3QG2Z8k059728 for ; Thu, 26 Apr 2007 16:02:35 GMT (envelope-from taleks@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l3QG2ZuP059723 for perforce@freebsd.org; Thu, 26 Apr 2007 16:02:35 GMT (envelope-from taleks@FreeBSD.org) Date: Thu, 26 Apr 2007 16:02:35 GMT Message-Id: <200704261602.l3QG2ZuP059723@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to taleks@FreeBSD.org using -f From: Alexey Tarasov To: Perforce Change Reviews Cc: Subject: PERFORCE change 118835 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Apr 2007 16:02:36 -0000 http://perforce.freebsd.org/chv.cgi?CH=118835 Change 118835 by taleks@taleks_th on 2007/04/26 16:01:49 Updated icmp code, added icmp echo replying. Affected files ... .. //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#2 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#2 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_icmp.c#2 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_ip.c#2 edit Differences ... ==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#2 (text+ko) ==== ==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#2 (text+ko) ==== @@ -4,6 +4,10 @@ #include #include +/* PXE structures and function codes +#include "sys/boot/libi386/pxe.h" +*/ + /* contains wrappers for UNDI functions */ @@ -60,6 +64,12 @@ /* interrupt handler function, that used to get new packets */ void pxe_core_isr(); +/* installs irq handler*/ +void pxe_core_install_isr(); + +/* removes irq handler*/ +void pxe_core_remove_isr(); + /* stores data in packet */ int pxe_core_recieve(pxe_packet* pack, void* data, size_t size); ==== //depot/projects/soc2007/taleks-pxe_http/pxe_icmp.c#2 (text+ko) ==== @@ -1,60 +1,164 @@ +#include #include "pxe_ip.h" #include "pxe_icmp.h" #include "pxe_core.h" #include "pxe_conv.h" +/* used in echo replying */ +static pinging=0; + int pxe_icmp_callback(pxe_packet* pack, uint8_t function, void* data) { - return 1; + + if (function==PXE_CORE_CHECK) { + /* we don't store icmp packets, so they cannot steal memory + in pxe core packet table */ + return 0; + } + + /* PXE_CORE_HANDLE - to handle packet + PXE_CORE_FRAG - to handle fragment of packet, may be useful for fast + dropping of invalid packet. + */ + + + /* icmp header*/ + pxe_ip* iphdr=pack->data; + size_t iphdr_len=(iphdr->ver_ihl & 0x0f)*4; + size_t data_size=iphdr->length-iphdr_len-sizeof(pxe_ip); + pxe_icmp* icmphdr=pack->data+sizeof(pxe_ip)+iphdr_len; + + /* TODO: verify checksum */ + + /* reply */ + pxe_packet* pack_out=NULL; + pxe_ip* reply_iphdr=NULL; + pxe_icmp* reply_icmphdr=NULL; + size_t reply_size=sizeof(pxe_ip)+sizeof(pxe_icmp)+data_size; + + /* we are interested only in echo related packets*/ + switch(icmphdr->code) { + case PXE_ICMP_ECHO_REQUEST: + case PXE_ICMP_ECHO_REPLY: + /* case PXE_ICMP_DEST_UNREACHABLE: + case PXE_ICMP_REDIRECT_MESSAGE: + */ + break; + + default: + return 0; /* instruct pxe core to drop packet*/ + }; + + if (icmphdr->code==PXE_ICMP_ECHO_REPLY) { + + if (pinging==be2le32(iphdr->src_ip)) + printf("\necho reply from %x, seq=%ld.", iphdr->src_ip, icmphdr->seq_num); + else /* we are not interested in this reply*/ + printf("\nlame echo reply from %x, seq=%ld.", iphdr->src_ip, icmphdr->seq_num); + return 0; + } + /* all we need now is echo reply */ + pxe_packet* pack_out=pxe_core_alloc_packet(reply_size); + + if (!pack) { /* TO THINK: failed to allocate packet, + may be it's better to use + statically allocated packet. */ + + return 0; + } + + reply_iphdr=(pxe_ip*)pack_out->data; + reply_icmphdr=(pxe_icmp*)(reply_iphdr+1); + + reply_icmphdr->type=PXE_ICMP_ECHO_REPLY; + + /* copying same values */ + + reply_icmphdr->code=icmphdr->code; + reply_icmphdr->seq_num=icmphdr->seq_num; + reply_icmphdr->packet_id=icmphdr->reply_icmphdr; + reply_icmphdr->checksum=0; + reply_icmphdr->checksum=~(le2be16(pxe_ip_checksum(reply_icmphdr, sizeof(pxe_icmp)))); + + pxe_ip_hdr(pack_out->data, iphdr->src_ip, 0x01, reply_size, 0); + + /*copying all data from request packet to reply packet, starting after headers */ + pxe_memcpy(reply_icmphdr+1, pack->data+iphdr_len+sizeof(pxe_icmp), data_size); + + pxe_core_transmit(pack_out); +/* pxe_core_commit(pack); + return 1; /* instruct core we are interested in it, so save data */ + + return 0; /* drop it, we don't need this packet more */ + /* this is a little bit ugly, may be */ + /* using of more return codes will be more flexible */ } int pxe_icmp_init() { - pxe_core_register(1, pxe_icmp_callback); + /* register protocol in pxe protocols table. */ + /* 0x01 - ICMP protocol */ + pxe_core_register(0x01, pxe_icmp_callback); return 1; } int pxe_ping(pxe_ipaddr* ip, int count) { - uint32_t scount=0; + int scount=0; /* creating packet */ - - pxe_packet* pack=pxe_core_alloc_packet(sizeof(pxe_ip)+sizeof(pxe_icmp)); + size_t pack_size=sizeof(pxe_ip)+sizeof(pxe_icmp)+32; + pxe_packet* pack=pxe_core_alloc_packet(pack_size); + pxe_ip* iphdr=NULL; + pxe_icmp* icmphdr=NULL; if (!pack) { /* failed to alloc packet */ return 0; } - pxe_ip* iphdr=pack->data; - pxe_icmp* icmphdr=pack->data+sizeof(pxe_ip); + printf("\nping: %x, bytes=32", ip->ip); + pinging=ip->ip; + + iphdr=(pxe_ip*)pack->data; + icmphdr=(pxe_icmp*)(pack->data+sizeof(pxe_ip)); + + /* base icmp header side*/ icmphdr->type=PXE_ICMP_ECHO_REQUEST; - icmphdr->code=0; - icmphdr->seq_num=0; - icmphdr->packet_id=0; - icmphdr->checksum=0; + icmphdr->code=1; + +/* icmphdr->seq_num=scount; + icmphdr->packet_id=scount*scount; +*/ + +/* icmphdr->checksum=0; + reply_icmphdr->checksum=~(le2be16(pxe_ip_checksum(icmphdr, sizeof(pxe_icmp)))); +*/ + + /* ip header side */ + pxe_ip_hdr(pack->data, ip->ip, 0x01, pack_size, 0); + + + while (scountseq_num=scount; + icmphdr->packet_id=scount*scount; /* is this good idea? */ -/* iphdr->checksum=0; - iphdr->length=le2be16(sizeof(pxe_ip)+sizeof(pxe_icmp)); - iphdr->protocol=1; - iphdr->checksum=0; - iphdr->data_off=le2be16(sizeof(pxe_ip)); - iphdr->dst_ip=le2be32(ip->ip); - iphdr->id=0; - iphdr->tos=0; - iphdr->src_ip=le2be32(pxe_get_myip32()); - iphdr->ttl=30; + /* recalc for every packet */ - iphdr->ver_ihl=0x45; + icmphdr->checksum=0; + reply_icmphdr->checksum=~(le2be16(pxe_ip_checksum(icmphdr, sizeof(pxe_icmp)))); -*/ + pxe_core_transmit(pack); - pxe_ip_hdr(pack->data, ip->ip, 1, sizeof(pxe_ip)+sizeof(pxe_icmp), 0); + /* TODO: timeout checking */ + ++scount; + } + pinging=0; return scount; } ==== //depot/projects/soc2007/taleks-pxe_http/pxe_ip.c#2 (text+ko) ==== @@ -24,6 +24,9 @@ return (uint16_t)sum; } +/* NOTE: opts_size is unused, cause we are creating header without options. + it may be useful later, but now it's just unused. +*/ void pxe_ip_hdr(void* data, uint32_t dst_ip, uint8_t protocol, uint16_t size, uint16_t opts_size) { pxe_ip* iphdr=(pxe_ip*)data; @@ -32,13 +35,16 @@ iphdr->length=size; iphdr->protocol=protocol; iphdr->checksum=0; - iphdr->data_off=0; /* le2be16(sizeof(pxe_ip)); */ + /* data_off - offset of fragment, need to think about renaming. */ + iphdr->data_off=0; /* le2be16(); */ iphdr->dst_ip=le2be32(dst_ip); iphdr->id=0; iphdr->tos=0; iphdr->src_ip=le2be32(pxe_get_myip32()); iphdr->ttl=30; + /* 0x45 [ver_ihl] = 0x4 << 4 [ip version] | + 0x5 [header length = 20 bytes, no opts] */ iphdr->ver_ihl=0x45; iphdr->ver_ihl+=(opts_size>>2)