PERFORCE change 118835 for review
Alexey Tarasov
taleks at FreeBSD.org
Thu Apr 26 16:02:36 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=118835
Change 118835 by taleks at 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 <stdint.h>
#include <stddef.h>
+/* 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 <stand.h>
#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 (scount<count) {
+
+ icmphdr->seq_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)
More information about the p4-projects
mailing list