|  | #include <multiboot.h> | 
|  | #include <arch/frontend.h> | 
|  | #include <net/nic_common.h> | 
|  | #include <kmalloc.h> | 
|  |  | 
|  | #define debug(...) printk(__VA_ARGS__) | 
|  |  | 
|  | int handle_appserver_packet(const char* p, size_t size) | 
|  | { | 
|  | // Subtract off the crc because we just don't care... | 
|  | size-=4; | 
|  |  | 
|  | appserver_packet_t* packet = (appserver_packet_t*)p; | 
|  |  | 
|  | if(size < sizeof(packet->header)) | 
|  | goto fail; | 
|  |  | 
|  | uint8_t cmd = packet->header.cmd; | 
|  | if(cmd != APPSERVER_CMD_LOAD && cmd != APPSERVER_CMD_STORE) | 
|  | goto fail; | 
|  |  | 
|  | uintptr_t paddr = ntohl(packet->header.addr); | 
|  | size_t copy_size = ntohl(packet->header.payload_size); | 
|  | if(paddr % 4 || paddr >= max_paddr) | 
|  | goto fail; | 
|  | if(copy_size % 4 || copy_size > APPSERVER_MAX_PAYLOAD_SIZE) | 
|  | goto fail; | 
|  |  | 
|  | size_t paysize = copy_size; | 
|  | size_t response_paysize = 0; | 
|  | if(cmd == APPSERVER_CMD_LOAD) | 
|  | { | 
|  | response_paysize = copy_size; | 
|  | paysize = 0; | 
|  | } | 
|  | if(size != sizeof(packet->header) + paysize && | 
|  | !(size == MIN_FRAME_SIZE && sizeof(packet->header) + paysize <= MIN_FRAME_SIZE)) | 
|  | goto fail; | 
|  |  | 
|  | // construct response packet | 
|  | size_t response_size = sizeof(packet->header)+response_paysize; | 
|  | appserver_packet_t* response_packet = kmalloc(response_size,0); | 
|  |  | 
|  | memcpy(response_packet->header.dst_mac,packet->header.src_mac,6); | 
|  | memcpy(response_packet->header.src_mac,packet->header.dst_mac,6); | 
|  | response_packet->header.ethertype = packet->header.ethertype; | 
|  | response_packet->header.cmd = APPSERVER_CMD_ACK; | 
|  | response_packet->header.seqno = packet->header.seqno; | 
|  | response_packet->header.payload_size = htonl(response_paysize); | 
|  | response_packet->header.addr = packet->header.addr; | 
|  |  | 
|  | // determine src/dest for copy | 
|  | const uint32_t* copy_src = (const uint32_t*)packet->payload; | 
|  | uint32_t* copy_dst = (uint32_t*)KADDR(paddr); | 
|  | if(cmd == APPSERVER_CMD_LOAD) | 
|  | { | 
|  | copy_src = copy_dst; | 
|  | copy_dst = (uint32_t*)response_packet->payload; | 
|  | } | 
|  |  | 
|  | // manual word-by-word copy for word-atomicity | 
|  | for(int i = 0; i < copy_size/sizeof(uint32_t); i++) | 
|  | copy_dst[i] = copy_src[i]; | 
|  |  | 
|  | // fire the response | 
|  | if(send_frame((char*)response_packet,response_size) != response_size) | 
|  | panic("couldn't send appserver packet!"); | 
|  | kfree(response_packet); | 
|  |  | 
|  | return 0; | 
|  |  | 
|  | fail: | 
|  | panic("bad appserver packet!"); | 
|  | } |