int WINAPI fake_sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen) { #ifdef _DEBUG printf("sendto(s=%d, buf=%p, len=%d, flags=%08X, to=%p, tolen=%d)\n", s, buf, len, flags, to, tolen); #endif if (to->sa_family == AF_IPX) { struct sockaddr_in to_in; if (dedicated) { if (is_ipx_broadcast((struct sockaddr_ipx *)to)) { net_write_int8(my_p2p ? 1 : 0); net_write_int32(0xFFFFFFFF); net_write_int16(0xFFFF); net_write_data((void *)buf, len); net_send(&server); } else { ipx2in((struct sockaddr_ipx *)to, &to_in); /* use p2p only if both clients are in p2p mode */ if (to_in.sin_zero[0] && my_p2p) { net_write_data((void *)buf, len); net_send(&to_in); } else { net_write_int8(my_p2p ? 1 : 0); net_write_int32(to_in.sin_addr.s_addr); net_write_int16(to_in.sin_port); net_write_data((void *)buf, len); net_send(&server); } } return len; } ipx2in((struct sockaddr_ipx *)to, &to_in); to_in.sin_port = htons(5000); // forcing the destination port net_write_data((void *)buf, len); /* check if it's a broadcast */ if (is_ipx_broadcast((struct sockaddr_ipx *)to)) { net_send(&server); return len; } else { return net_send(&to_in); } } return sendto(s, buf, len, flags, to, tolen); }
/* * PACKET_BUFFER_CONTENTS format (CPU): * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 1 | 1 if this is the read buffer, 2 if it's write * 12 | 512 | Contents of the buffer */ int pkt_send_buffer_contents(struct sd *sd, uint8_t buffertype, uint8_t *buffer) { char pkt[PKT_HEADER_SIZE+1+512]; pkt_set_header(sd, pkt, PACKET_BUFFER_CONTENTS, sizeof(pkt)); pkt[PKT_HEADER_SIZE+0] = buffertype; memcpy(pkt+PKT_HEADER_SIZE+1, buffer, 512); return net_write_data(sd, pkt, sizeof(pkt)); }
int pkt_send_sd_cmd_arg(struct sd *sd, uint8_t regnum, uint8_t val) { char pkt[PKT_HEADER_SIZE+1+1]; pkt_set_header(sd, pkt, PACKET_SD_CMD_ARG, sizeof(pkt)); pkt[PKT_HEADER_SIZE+0] = regnum; pkt[PKT_HEADER_SIZE+1] = val; return net_write_data(sd, pkt, sizeof(pkt)); }
/* * PACKET_BUFFER_OFFSET format (CPU): * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 1 | 1 if this is the read buffer, 2 if it's write * 12 | 4 | Offset of the current buffer pointer */ int pkt_send_buffer_offset(struct sd *sd, uint8_t buffertype, uint32_t offset) { char pkt[PKT_HEADER_SIZE+1+4]; uint32_t real_offset; pkt_set_header(sd, pkt, PACKET_BUFFER_OFFSET, sizeof(pkt)); real_offset = htonl(offset); pkt[PKT_HEADER_SIZE+0] = buffertype; memcpy(pkt+PKT_HEADER_SIZE+1, &real_offset, sizeof(real_offset)); return net_write_data(sd, pkt, sizeof(pkt)); }
/* * PACKET_NAND_CYCLE format (FPGA): * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 1 | Data/Command pins * 12 | 1 | Bits [0..4] are ALE, CLE, WE, RE, and CS (in order) * 13 | 2 | Bits [0..9] are the unknown pins */ int pkt_send_nand_cycle(struct sd *sd, uint32_t fpga_counter, uint8_t data, uint8_t ctrl, uint8_t unk[2]) { char pkt[PKT_HEADER_SIZE+1+1+2]; pkt_set_header_fpga(sd, pkt, fpga_counter, PACKET_NAND_CYCLE, sizeof(pkt)); pkt[PKT_HEADER_SIZE+0] = data; pkt[PKT_HEADER_SIZE+1] = ctrl; pkt[PKT_HEADER_SIZE+2] = unk[0]; pkt[PKT_HEADER_SIZE+3] = unk[1]; return net_write_data(sd, pkt, sizeof(pkt)); }
/* * PACKET_COMMAND format (CPU): * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 2 | Two-character command code * 13 | 4 | 32-bit command argument * 14 | 1 | 1 if the command is starting, 2 if it's ending */ int pkt_send_command(struct sd *sd, struct sd_cmd *cmd, uint8_t start_stop) { char pkt[PKT_HEADER_SIZE+2+4+1]; uint32_t arg; arg = htonl(cmd->arg); pkt_set_header(sd, pkt, PACKET_COMMAND, sizeof(pkt)); pkt[PKT_HEADER_SIZE+0] = cmd->cmd[0]; pkt[PKT_HEADER_SIZE+1] = cmd->cmd[1]; memcpy(pkt+PKT_HEADER_SIZE+2, &arg, sizeof(arg)); pkt[PKT_HEADER_SIZE+2+4] = start_stop; return net_write_data(sd, pkt, sizeof(pkt)); }
/* PKT_ERROR * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 4 | Error code * 15 | 512 | Textual error message (NULL-padded) */ int pkt_send_error(struct sd *sd, uint32_t code, char *msg) { char pkt[PKT_HEADER_SIZE+4+512]; uint32_t real_code; bzero(pkt, sizeof(pkt)); pkt_set_header(sd, pkt, PACKET_ERROR, sizeof(pkt)); real_code = htonl(code); memcpy(pkt+PKT_HEADER_SIZE+0, &real_code, sizeof(real_code)); strncpy(pkt+PKT_HEADER_SIZE+4, msg, 512-1); return net_write_data(sd, pkt, sizeof(pkt)); }
/* * PACKET_HELLO format (CPU): * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 1 | Command stream version number */ int pkt_send_hello(struct sd *sd) { char pkt[PKT_HEADER_SIZE+1]; pkt_set_header(sd, pkt, PACKET_HELLO, sizeof(pkt)); pkt[PKT_HEADER_SIZE+0] = PKT_VERSION_NUMBER; return net_write_data(sd, pkt, sizeof(pkt)); }
/* * PACKET_BUFFER_DRAIN format (CPU): * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 1 | 1 if it's a buffer drain start, 2 if it's an end */ int pkt_send_buffer_drain(struct sd *sd, uint8_t start_stop) { char pkt[PKT_HEADER_SIZE+1]; pkt_set_header(sd, pkt, PACKET_BUFFER_DRAIN, sizeof(pkt)); pkt[PKT_HEADER_SIZE+0] = start_stop; return net_write_data(sd, pkt, sizeof(pkt)); }
/* * PACKET_SD_CSD format (CPU): * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 16 | Contents of the card's CSD */ int pkt_send_sd_csd(struct sd *sd, uint8_t csd[16]) { char pkt[PKT_HEADER_SIZE+16]; pkt_set_header(sd, pkt, PACKET_SD_CSD, sizeof(pkt)); memcpy(pkt+PKT_HEADER_SIZE, csd, 16); return net_write_data(sd, pkt, sizeof(pkt)); }
/* * PACKET_SD_RESPONSE format (FPGA): * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 1 | The contents of the first byte that the card answered with */ int pkt_send_sd_response(struct sd *sd, uint8_t byte) { char pkt[PKT_HEADER_SIZE+1]; pkt_set_header(sd, pkt, PACKET_SD_RESPONSE, sizeof(pkt)); pkt[PKT_HEADER_SIZE+0] = byte; return net_write_data(sd, pkt, sizeof(pkt)); }
/* * PACKET_SD_DATA format (CPU): * Offset | Size | Description * --------+------+------------- * 0 | 11 | Header * 11 | 512 | One block of data from the card */ int pkt_send_sd_data(struct sd *sd, uint8_t *block) { char pkt[PKT_HEADER_SIZE+512]; pkt_set_header(sd, pkt, PACKET_SD_DATA, sizeof(pkt)); memcpy(pkt+PKT_HEADER_SIZE, block, 512); return net_write_data(sd, pkt, sizeof(pkt)); }