Date: Mon, 21 May 2007 17:14:00 GMT From: Alexey Tarasov <taleks@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 120182 for review Message-ID: <200705211714.l4LHE02j026218@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=120182 Change 120182 by taleks@taleks_th on 2007/05/21 17:13:03 Added check of frame size to pxe_core_recv_packets() to avoid run-time memory problems. Modified pxe_core_call() status understanding behaviour. From this day it checks not AX register (now: API call_status), but Status field of used structure in API call (status). It seems, all available PXE implementations now work well. Removed some useless code in pxe_core_init(), need to test it on more NICs and remove last commented lines related to UNDI_SHUTDOWN and UNDI_INITIALIZE. Affected files ... .. //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#9 edit Differences ... ==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#9 (text+ko) ==== @@ -214,43 +214,8 @@ /* 2. additional start UNDI */ - /* 2.2 unload stack */ -/* t_PXENV_UNLOAD_STACK *unload_stack = - (t_PXENV_UNLOAD_STACK *)scratch_buffer; - - pxe_memset(unload_stack, 0, sizeof(t_PXENV_UNLOAD_STACK)); - - pxe_core_call(PXENV_UNLOAD_STACK); - - delay(10000000); -*/ - - /* 2.1 stop base */ -/* t_PXENV_STOP_BASE *base_stop = - (t_PXENV_STOP_BASE *)scratch_buffer; - - base_stop->Status = 0; - - pxe_core_call(PXENV_STOP_BASE); - - delay(10000000); -*/ - uint8_t ustate = 3; + /* 2.1 close connection to network */ /* - t_PXENV_UNDI_GET_STATE *undi_state = - (t_PXENV_UNDI_GET_STATE *)scratch_buffer; - - pxe_core_call(PXENV_UNDI_GET_STATE); - - ustate=undi_state->UNDIstate; - printf("UNDI state: %d\n", ustate); - - delay(5000000); -*/ - /* close */ -/* - if (ustate == 3) { - t_PXENV_UNDI_CLOSE *undi_close = (t_PXENV_UNDI_CLOSE *)scratch_buffer; @@ -260,94 +225,32 @@ delay(10000000); } */ - /* cleanup */ -/* - if (ustate > 1) { - t_PXENV_UNDI_CLEANUP *undi_cleanup = - (t_PXENV_UNDI_CLEANUP *)scratch_buffer; + /* 2.1. shutdown UNDI */ + +/* t_PXENV_UNDI_SHUTDOWN *undi_shutdown = + (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer; - undi_cleanup->Status = 0; + undi_shutdown->Status = 0; - pxe_core_call(PXENV_UNDI_CLEANUP); - - delay(10000000); - } - + pxe_core_call(PXENV_UNDI_SHUTDOWN); */ - /* shutdown */ -/* if (ustate > 0) { - t_PXENV_UNDI_SHUTDOWN *undi_shutdown = - (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer; - - undi_shutdown->Status = 0; - - pxe_core_call(PXENV_UNDI_SHUTDOWN); - - delay(10000000); - } -*/ - -/* - if (ustate < 1) { - if (!pxe_core_undi_startup()) { - return (0); - } else { - ustate = 1; - } - } else { - printf("Skipping startup due to UNDI state.\n"); - } -*/ - -/* if (ustate < 2) { - if (!pxe_core_undi_init()) { - return (0); - } else { - ustate = 2; - } - } else { - printf("Skipping initialization due to UNDI state.\n"); + /* 2.2 init UNDI */ +/* if (!pxe_core_undi_init()) { + return (0); } - - delay(10000000); */ - - /* reset */ -/* t_PXENV_UNDI_RESET *undi_reset = (t_PXENV_UNDI_RESET *)scratch_buffer; - - pxe_memset(undi_reset, 0, sizeof(t_PXENV_UNDI_RESET)); - undi_reset->R_Mcast_Buf.MCastAddrCount = 0; - - if (!pxe_core_call(PXENV_UNDI_RESET_ADAPTER)) { - } -*/ /* 3. install isr */ pxe_core_install_isr(); - /* set station addreess */ -/* if (ustate < 3) { - t_PXENV_UNDI_SET_STATION_ADDR *undi_addr= - (t_PXENV_UNDI_SET_STATION_ADDR *)scratch_buffer; - - pxe_memset(undi_addr, 0, sizeof(t_PXENV_UNDI_SET_STATION_ADDR)); - pxe_memcpy(&bootplayer.CAddr, undi_addr->StationAddress, 6); - - if (!pxe_core_call(PXENV_UNDI_SET_STATION_ADDRESS)) { - } - + /* 4. open connection to network */ + t_PXENV_UNDI_OPEN *undi_open = (t_PXENV_UNDI_OPEN *)scratch_buffer; - t_PXENV_UNDI_OPEN *undi_open = (t_PXENV_UNDI_OPEN *)scratch_buffer; - - pxe_memset(undi_open, 0, sizeof(t_PXENV_UNDI_OPEN)); - undi_open->PktFilter = FLTR_DIRECTED | FLTR_BRDCST; - undi_open->R_Mcast_Buf.MCastAddrCount = 0; + pxe_memset(undi_open, 0, sizeof(t_PXENV_UNDI_OPEN)); + undi_open->PktFilter = FLTR_DIRECTED | FLTR_BRDCST; + undi_open->R_Mcast_Buf.MCastAddrCount = 0; - if (!pxe_core_call(PXENV_UNDI_OPEN)) { - } - ustate =3; - - } -*/ + if (!pxe_core_call(PXENV_UNDI_OPEN)) { + } /* saving information about NIC */ nic_ip.ip = bootplayer.yip; /* my ip */ @@ -360,7 +263,7 @@ printf("pxe_core_init(): ended.\n"); #endif - delay(20000000); + delay(5000000); return (1); } @@ -483,7 +386,7 @@ /* * function code is taken from bangpxe_call(), /sys/boot/libi386/pxe.c - * needs pxe_isr.s wrapper and vm86int() support. + * needs pxe_srs.s wrapper and vm86int() support. * in: * func - PXE function number * out: @@ -497,8 +400,7 @@ #ifdef PXE_DEBUG printf("pxe_core_call(): func = 0x%x...", func); #endif - bzero(&v86, sizeof(v86)); -/* bzero(data_buffer, sizeof(data_buffer));*/ + pxe_memset(&v86, 0, sizeof(v86)); v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; v86.edx = VTOPSEG(scratch_buffer); @@ -507,9 +409,12 @@ v86.ebx = func; v86int(); v86.ctl = V86_FLAGS; - int status = v86.eax; + + int call_status = v86.eax; + int status = *((uint16_t *)scratch_buffer); + #ifdef PXE_DEBUG - printf("%s (0x%x)\n", (status == 0) ? "OK" : "NOK", *((uint16_t *)scratch_buffer) ); + printf("%s (0x%x)\n", (call_status == 0) ? "?OK" : "?NOK", status ); #endif return (status == 0) ? 1 : 0; @@ -518,8 +423,7 @@ int pxe_core_transmit(PXE_PACKET *pack) { - /* NOTE:all provided data must be in base memory, - * if it's not here, it must be copied here (TO IMPLEMENT) + /* NOTE: is all provided data must be in base memory? */ t_PXENV_UNDI_TRANSMIT *undi_send = (t_PXENV_UNDI_TRANSMIT *)scratch_buffer; @@ -790,8 +694,16 @@ drop_flag = 1; /* clear queue, receiving all frames of packet */ } - pxe_core_copy( undi_isr->Frame.segment, undi_isr->Frame.offset, + /* sanity check */ + if (frame_size < PXE_BUFFER_SIZE) { + pxe_core_copy( undi_isr->Frame.segment, undi_isr->Frame.offset, VTOPSEG(data_buffer), VTOPOFF(data_buffer), frame_size); + } else { + printf("pxe_core_recv_packets(): not enough buffer size (%d bytes) for frame size %d bytes.", + PXE_BUFFER_SIZE, frame_size); + + drop_flag = 1; /* drop this packet */ + } /* checking first fragment, this may help to avoid memory allocation @@ -810,9 +722,6 @@ dummy_pack.data = data_buffer + MEDIAHDR_LEN_ETH; dummy_pack.data_size = frame_size - MEDIAHDR_LEN_ETH; -/* dummy_pack.data = frame_data; - dummy_pack.data_size = frame_size; -*/ dummy_pack.user_data = NULL; @@ -871,12 +780,19 @@ break; frame_size = undi_isr->FrameLength; -/* how to get in this address from userspace, which starts at 0xa800?*/ -/* frame_data = undi_isr->Frame.segment << 4 + undi_isr->Frame.offset; */ + + if (frame_size < PXE_BUFFER_SIZE) { + pxe_core_copy( undi_isr->Frame.segment, undi_isr->Frame.offset, + VTOPSEG(data_buffer), VTOPOFF(data_buffer), frame_size); + } else { + printf("pxe_core_recv_packets(): not enough buffer size (%d bytes) for frame size %d bytes.", + PXE_BUFFER_SIZE, frame_size); + drop_flag = 1; /* drop this packet */ + } if (!drop_flag) - pxe_core_recieve(pack, frame_data, frame_size); + pxe_core_recieve(pack, data_buffer, frame_size); received += frame_size; } @@ -884,7 +800,7 @@ if (received < buffer_size) { /* pxe_core_get_packet() in cycle failed */ if (!drop_flag) - pxe_core_drop(pack); + pxe_core_drop(pack); /* !!TODO: check, if we have this memory leak in some cases */ return (processed_packets); /* it's failed, finish receive cycle */ } @@ -912,7 +828,7 @@ func = PXENV_UNDI_ISR_IN_GET_NEXT; if (received == buffer_size) - return processed_packets; + return processed_packets; goto packet_start;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200705211714.l4LHE02j026218>