/** * \brief Blocking receive of an IR transmission, with optional timeout * \param buf The buffer in which to place the received data * \param timeout The time to wait before returning * \param startstop Whether to remove start/stop bits from transmission * \return The length of the buffer in bytes. * * Receive a message if it's there to be received. Otherwise wait for a time * that depends on the timeout value: if this is zero (as it is by default), * then wait forever, else set a timer. If the timer expires return a negative * number (-1), else return the length of the buffer received. The timeout is * considered not to have expired if, by the time the period is passed, a * message has *started* to arrive. * * The first received bit is placed in the MSB, meaning that if there is not * a complete byte's worth of data, the lowest bits will be zero. * * Note: Differentiating between a mark and a space is based on a hardwired * test of length. * */ int EngduinoIRClass::recv(uint8_t *buf, uint16_t timeout, bool startstop) { static uint16_t raw[RAWBUFSZ]; uint8_t b = 0; // The byte we're building uint8_t l = 0; // length of the buffer we've built int len = recvRaw(raw, timeout); if (len < 0) return len; if (startstop) len = len - 1; // Remove the stop bit. // The start bit isn't represented directly - it starts the timer. for (int i = 0; i < len; i++) { if (raw[i] < MARKSPACESPLIT) { // It's a mark. // Shift in the appropriate one // b |= (1 << (i%8)); } if ((i+1)%8 == 0) { buf[l++] = b; b = 0; } } // If there's anything left, add it to the // list if ((len % 8) != 0) { buf[l++] = b; } return l; }
// Main int main(int argc, char **argv) { // ----------- Variable char recv_packet[BUFF_SIZE+40]; struct iphdr * ip_header = (struct iphdr *) recv_packet; struct tcphdr * tcp_header = 0; // ----------- Start printf("\nStart Deflector\n\n"); // ----------- Raw Socket printf("Create Raw Socket(Receive)\n"); int recv_socket = socketRaw(IPPROTO_TCP, DEFLECTOR_PORT); // ----------- UDP printf("Create UDP Socket(Send)\n"); int send_socket = socket( PF_INET, SOCK_DGRAM, 0 ); struct sockaddr_in bypass_addr; memset( &bypass_addr, 0, sizeof(bypass_addr) ); bypass_addr.sin_family = AF_INET; bypass_addr.sin_port = htons(BYPASS_PORT); bypass_addr.sin_addr.s_addr = inet_addr(BYPASS_ADDR); // ----------- Main Loop printf("Enter Main Loop\n"); while(1) { recvRaw( recv_socket, recv_packet, sizeof(recv_packet) ); tcp_header = (struct tcphdr *) (recv_packet + ip_header->ihl * 4); if ( ntohs( tcp_header->dest ) == DEFLECTOR_PORT ) { tcp_header = (struct tcphdr *) (recv_packet + ip_header->ihl * 4); tcp_header->check = 0; tcp_header->check = tcp_checksum(ip_header, tcp_header); ip_header->check = 0; ip_header->check = checksum2((unsigned short*)ip_header, sizeof(struct iphdr)); // ----------- Receive Packet printf("\nReceive Packet\n"); #ifdef DEBUG_DEFLECTOR printf("----------------------------------------\n"); printf( "[ 패킷을 받았습니다. ]\n" ); printf( "발신자 IP : %s\n", inet_ntoa( * (struct in_addr*) &ip_header->saddr) ); printf( "발신자 Port : %5u\n", ntohs(tcp_header->source) ); printf( "수신자 IP : %s\n", inet_ntoa( * (struct in_addr*) &ip_header->daddr) ); printf( "수신자 Port : %5u\n", ntohs(tcp_header->dest) ); printf( "IP packet size : %d\n", ntohs(ip_header->tot_len)); printf( "IP check : %d\n", ip_header->check ); printf( "IP Version : %d\n", ip_header->version ); // IP 버전 정보 출력 printf( "Time To Live : %d\n", ip_header->ttl ); // TTL 정보 출력 printf( "TCP check : %d\n", tcp_header->check ); printf( "Window Size : %d\n", tcp_header->window ); // 윈도우 사이즈 정보 출력 printf( "Flags : " ); // 플래그 정보 출력 if( tcp_header->fin == 1 ) printf( "[FIN]\n" ); if( tcp_header->syn == 1 ) printf( "[SYN]\n" ); if( tcp_header->rst == 1 ) printf( "[RST]\n" ); if( tcp_header->psh == 1 ) printf( "[PSH]\n" ); if( tcp_header->ack == 1 ) printf( "[ACK]\n" ); if( tcp_header->urg == 1 ) printf( "[URG]\n" ); printf("-----------------------------------------\n"); #endif // ----------- Send UDP Packet printf("Send UDP Packet\n"); sendto( send_socket, (void *) &recv_packet, sizeof(recv_packet)+1, 0, (struct sockaddr *) &bypass_addr, sizeof(bypass_addr) ); } } }