diff --git a/src/rawnet/CMakeLists.txt b/src/rawnet/CMakeLists.txt index c43e371..1ff2337 100644 --- a/src/rawnet/CMakeLists.txt +++ b/src/rawnet/CMakeLists.txt @@ -3,17 +3,19 @@ if(WIN32) set(rawnetarch rawnetarch_win32.c) elseif(APPLE) set(rawnetarch rawnetarch_darwin.c) + #set(rawnetarch rawnetarch_unix.c) elseif(UNIX) set(rawnetarch rawnetarch_unix.c) endif() -add_library(rawnet cs8900.c rawnet.c rawnetsupp.c ${rawnetarch}) +add_library(rawnet cs8900.c rawnet.c rawnetsupp.c rawnetarch.c ${rawnetarch}) target_compile_definitions(rawnet PUBLIC HAVE_RAWNET) -target_compile_definitions(rawnet PRIVATE CS8900_DEBUG CS8900_DEBUG_STORE CS8900_DEBUG_LOAD) +target_compile_definitions(rawnet PRIVATE CS8900_DEBUG RAWNET_DEBUG_FRAMES) if(WIN32) elseif(APPLE) + #target_link_libraries(rawnet PRIVATE pcap) target_link_libraries(rawnet PRIVATE "-framework vmnet") elseif(UNIX) target_link_libraries(rawnet PRIVATE pcap) diff --git a/src/rawnet/rawnetarch.c b/src/rawnet/rawnetarch.c new file mode 100644 index 0000000..560b918 --- /dev/null +++ b/src/rawnet/rawnetarch.c @@ -0,0 +1,144 @@ +/** \file rawnetarch.c + * \brief raw ethernet interface, architecture-dependant stuff + * + * \author Bas Wassink + +#ifdef HAVE_RAWNET + +/* backward compatibility junk */ + + +/** \brief Transmit a frame + * + * \param[in] force Delete waiting frames in transmit buffer + * \param[in] onecoll Terminate after just one collision + * \param[in] inhibit_crc Do not append CRC to the transmission + * \param[in] tx_pad_dis Disable padding to 60 Bytes + * \param[in] txlength Frame length + * \param[in] txframe Pointer to the frame to be transmitted + */ +void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, + int tx_pad_dis, int txlength, uint8_t *txframe) +{ + + int ok; + +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, + "rawnet_arch_transmit() called, with: force = %s, onecoll = %s, " + "inhibit_crc=%s, tx_pad_dis=%s, txlength=%u", + force ? "TRUE" : "FALSE", + onecoll ? "TRUE" : "FALSE", + inhibit_crc ? "TRUE" : "FALSE", + tx_pad_dis ? "TRUE" : "FALSE", + txlength); +#endif + + ok = rawnet_arch_write(txframe, txlength); + if (ok < 0) { + log_message(rawnet_arch_log, "WARNING! Could not send packet!"); + } +} + +/** + * \brief Check if a frame was received + * + * This function checks if there was a frame received. If so, it returns 1, + * else 0. + * + * If there was no frame, none of the parameters is changed! + * + * If there was a frame, the following actions are done: + * + * - at maximum \a plen byte are transferred into the buffer given by \a pbuffer + * - \a plen gets the length of the received frame, EVEN if this is more + * than has been copied to \a pbuffer! + * - if the dest. address was accepted by the hash filter, \a phashed is set, + * else cleared. + * - if the dest. address was accepted by the hash filter, \a phash_index is + * set to the number of the rule leading to the acceptance + * - if the receive was ok (good CRC and valid length), \a *prx_ok is set, else + * cleared. + * - if the dest. address was accepted because it's exactly our MAC address + * (set by rawnet_arch_set_mac()), \a pcorrect_mac is set, else cleared. + * - if the dest. address was accepted since it was a broadcast address, + * \a pbroadcast is set, else cleared. + * - if the received frame had a crc error, \a pcrc_error is set, else cleared + * + * \param[out] buffer where to store a frame + * \param[in,out] plen IN: maximum length of frame to copy; + * OUT: length of received frame OUT + * can be bigger than IN if received frame was + * longer than supplied buffer + * \param[out] phashed set if the dest. address is accepted by the + * hash filter + * \param[out] phash_index hash table index if hashed == TRUE + * \param[out] prx_ok set if good CRC and valid length + * \param[out] pcorrect_mac set if dest. address is exactly our IA + * \param[out[ pbroadcast set if dest. address is a broadcast address + * \param[out] pcrc_error set if received frame had a CRC error +*/ +int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed, + int *phash_index, int *prx_ok, int *pcorrect_mac, int *pbroadcast, + int *pcrc_error) +{ + int ok; + +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, + "rawnet_arch_receive() called, with *plen=%u.", + *plen); +#endif + + + + assert((*plen & 1) == 0); + + ok = rawnet_arch_read(pbuffer, *plen); + if (ok < 0) return 0; + + if (ok & 1) ++ok; + *plen = ok; + + *phashed = + *phash_index = + *pbroadcast = + *pcorrect_mac = + *pcrc_error = 0; + + /* this frame has been received correctly */ + *prx_ok = 1; + return 1; + +} + + + + +#endif /* ifdef HAVE_RAWNET */ diff --git a/src/rawnet/rawnetarch.h b/src/rawnet/rawnetarch.h index 4b76204..68ddc68 100644 --- a/src/rawnet/rawnetarch.h +++ b/src/rawnet/rawnetarch.h @@ -66,6 +66,9 @@ extern int rawnet_arch_enumadapter_close(void); extern char *rawnet_arch_get_standard_interface(void); +extern int rawnet_arch_read(void *buffer, int length); +extern int rawnet_arch_write(const void *buffer, int length); + extern int rawnet_arch_get_mtu(void); extern int rawnet_arch_get_mac(uint8_t mac[6]); diff --git a/src/rawnet/rawnetarch_darwin.c b/src/rawnet/rawnetarch_darwin.c index 582f832..e52a173 100644 --- a/src/rawnet/rawnetarch_darwin.c +++ b/src/rawnet/rawnetarch_darwin.c @@ -347,52 +347,7 @@ static void fix_outgoing_packet(uint8_t *packet, unsigned size, const uint8_t re } - -void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, int tx_pad_dis, int txlength, uint8_t *txframe) { - - int count = 1; - vmnet_return_t st; - struct vmpktdesc v; - struct iovec iov; - - if (txlength == 0) return; - if (txlength > interface_packet_size) { - log_message(rawnet_arch_log, "packet is too big: %d", txlength); - return; - } - - if (txlength < 12) { - log_message(rawnet_arch_log, "packet is too small: %d", txlength); - return; - } - - /* copy the buffer and fix the source mac address. */ - memcpy(interface_buffer, txframe, txlength); - fix_outgoing_packet(interface_buffer, txlength, interface_mac, interface_fake_mac); - - iov.iov_base = interface_buffer; - iov.iov_len = txlength; - - v.vm_pkt_size = txlength; - v.vm_pkt_iov = &iov; - v.vm_pkt_iovcnt = 1; - v.vm_flags = 0; - - - fprintf(stderr, "\nrawnet_arch_transmit: %u\n", (unsigned)iov.iov_len); - rawnet_hexdump(interface_buffer, v.vm_pkt_size); - - - st = vmnet_write(interface, &v, &count); - - if (st != VMNET_SUCCESS) { - log_message(rawnet_arch_log, "vmnet_write failed!"); - } - return; -} - -int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed, int *phash_index, int *prx_ok, int *pcorrect_mac, int *pbroadcast, int *pcrc_error) { - +int rawnet_arch_read(void *buffer, int nbyte) { int count = 1; int xfer; @@ -410,8 +365,8 @@ int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed, int *phash_in st = vmnet_read(interface, &v, &count); if (st != VMNET_SUCCESS) { - log_message(rawnet_arch_log, "vmnet_write failed!"); - return 0; + log_message(rawnet_arch_log, "vmnet_read failed!"); + return -1; } if (count < 1) { @@ -427,40 +382,54 @@ int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed, int *phash_in } xfer = v.vm_pkt_size; - if (xfer > *plen) xfer = *plen; - memcpy(pbuffer, interface_buffer, xfer); + memcpy(buffer, interface_buffer, xfer); - xfer = v.vm_pkt_size; - if (xfer & 0x01) ++xfer; /* ??? */ - *plen = xfer; /* actual frame size */ - - *phashed = - *phash_index = - *pbroadcast = - *pcorrect_mac = - *pcrc_error = 0; - - *prx_ok = 1; - #if 0 - *pcorrect_mac = memcmp(interface_buffer, interface_mac, 6) == 0; - *pbroadcast = memcmp(interface_buffer, broadcast_mac, 6) == 0; - #endif - - /* vmnet won't send promiscuous packets */ - #if 0 - hashreg = (~crc32_buf(interface_buffer, 6) >> 26) & 0x3f; - if (hash_mask[hashreg >= 32] & (1 << (hashreg & 0x1F))) { - *phashed = 1; - *phash_index = hashreg; - } else { - *phashed = 0; - *phash_index = 0; - } - #endif - - return 1; + return xfer; } +int rawnet_arch_write(const void *buffer, int nbyte) { + + int count = 1; + vmnet_return_t st; + struct vmpktdesc v; + struct iovec iov; + + if (nbyte <= 0) return 0; + + if (nbyte > interface_packet_size) { + log_message(rawnet_arch_log, "packet is too big: %d", nbyte); + return -1; + } + + /* copy the buffer and fix the source mac address. */ + memcpy(interface_buffer, buffer, nbyte); + fix_outgoing_packet(interface_buffer, nbyte, interface_mac, interface_fake_mac); + + iov.iov_base = interface_buffer; + iov.iov_len = nbyte; + + v.vm_pkt_size = nbyte; + v.vm_pkt_iov = &iov; + v.vm_pkt_iovcnt = 1; + v.vm_flags = 0; + + + fprintf(stderr, "\nrawnet_arch_transmit: %u\n", (unsigned)iov.iov_len); + rawnet_hexdump(interface_buffer, v.vm_pkt_size); + + + st = vmnet_write(interface, &v, &count); + + if (st != VMNET_SUCCESS) { + log_message(rawnet_arch_log, "vmnet_write failed!"); + return -1; + } + return nbyte; +} + + + + static unsigned adapter_index = 0; int rawnet_arch_enumadapter_open(void) { adapter_index = 0; diff --git a/src/rawnet/rawnetarch_tap.c b/src/rawnet/rawnetarch_tap.c index 7b886cb..cc596b7 100644 --- a/src/rawnet/rawnetarch_tap.c +++ b/src/rawnet/rawnetarch_tap.c @@ -142,23 +142,12 @@ void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver) { /* NOP */ } -void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, int tx_pad_dis, int txlength, uint8_t *txframe) { - - ssize_t ok = write(interface_fd, txframe, txlength); +int rawnet_arch_read(void *buffer, int nbyte) { + return read(interface_fd, buffer, nbyte); } - -int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed, int *phash_index, int *prx_ok, int *pcorrect_mac, int *pbroadcast, int *pcrc_error) { - - int count = *plen; - ssize_t ok = read(interface_fd, pbuffer, count); - if (ok < 0) return 0; - if (ok & 0x01) ++ok; /* ??? */ - *plen = ok; - *prx_ok = 1; - *phashed = *pcorrect_mac = *pbroadcast = *pcrc_error = 0; - - return 1; +int rawnet_arch_write(const void *buffer, int nbyte) { + return write(interface_fd, buffer, nbyte); } diff --git a/src/rawnet/rawnetarch_unix.c b/src/rawnet/rawnetarch_unix.c index fb1541c..4177b76 100644 --- a/src/rawnet/rawnetarch_unix.c +++ b/src/rawnet/rawnetarch_unix.c @@ -388,30 +388,25 @@ static int rawnet_arch_receive_frame(rawnet_pcap_internal_t *pinternal) return ret; } +int rawnet_arch_read(void *buffer, int nbyte) { -/** \brief Transmit a frame - * - * \param[in] force Delete waiting frames in transmit buffer - * \param[in] onecoll Terminate after just one collision - * \param[in] inhibit_crc Do not append CRC to the transmission - * \param[in] tx_pad_dis Disable padding to 60 Bytes - * \param[in] txlength Frame length - * \param[in] txframe Pointer to the frame to be transmitted - */ -void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, - int tx_pad_dis, int txlength, uint8_t *txframe) -{ + int len; -#ifdef RAWNET_DEBUG_ARCH - log_message(rawnet_arch_log, - "rawnet_arch_transmit() called, with: force = %s, onecoll = %s, " - "inhibit_crc=%s, tx_pad_dis=%s, txlength=%u", - force ? "TRUE" : "FALSE", - onecoll ? "TRUE" : "FALSE", - inhibit_crc ? "TRUE" : "FALSE", - tx_pad_dis ? "TRUE" : "FALSE", - txlength); -#endif + rawnet_pcap_internal_t internal = { nbyte, (uint8_t *)buffer }; + + len = rawnet_arch_receive_frame(&internal); + + if (len <= 0) return len; + +#ifdef RAWNET_DEBUG_PKTDUMP + debug_output("Received frame: ", internal.buffer, internal.len); +#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */ + return len; + +} + + +int rawnet_arch_write(const void *buffer, int nbyte) { #ifdef RAWNET_DEBUG_PKTDUMP debug_output("Transmit frame: ", txframe, txlength); @@ -419,97 +414,12 @@ void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, if (pcap_sendpacket(rawnet_pcap_fp, txframe, txlength) < 0) { log_message(rawnet_arch_log, "WARNING! Could not send packet!"); + return -1; } + return nbyte; } -/** - * \brief Check if a frame was received - * - * This function checks if there was a frame received. If so, it returns 1, - * else 0. - * - * If there was no frame, none of the parameters is changed! - * - * If there was a frame, the following actions are done: - * - * - at maximum \a plen byte are transferred into the buffer given by \a pbuffer - * - \a plen gets the length of the received frame, EVEN if this is more - * than has been copied to \a pbuffer! - * - if the dest. address was accepted by the hash filter, \a phashed is set, - * else cleared. - * - if the dest. address was accepted by the hash filter, \a phash_index is - * set to the number of the rule leading to the acceptance - * - if the receive was ok (good CRC and valid length), \a *prx_ok is set, else - * cleared. - * - if the dest. address was accepted because it's exactly our MAC address - * (set by rawnet_arch_set_mac()), \a pcorrect_mac is set, else cleared. - * - if the dest. address was accepted since it was a broadcast address, - * \a pbroadcast is set, else cleared. - * - if the received frame had a crc error, \a pcrc_error is set, else cleared - * - * \param[out] buffer where to store a frame - * \param[in,out] plen IN: maximum length of frame to copy; - * OUT: length of received frame OUT - * can be bigger than IN if received frame was - * longer than supplied buffer - * \param[out] phashed set if the dest. address is accepted by the - * hash filter - * \param[out] phash_index hash table index if hashed == TRUE - * \param[out] prx_ok set if good CRC and valid length - * \param[out] pcorrect_mac set if dest. address is exactly our IA - * \param[out[ pbroadcast set if dest. address is a broadcast address - * \param[out] pcrc_error set if received frame had a CRC error -*/ -int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed, - int *phash_index, int *prx_ok, int *pcorrect_mac, int *pbroadcast, - int *pcrc_error) -{ - int len; - - rawnet_pcap_internal_t internal = { *plen, pbuffer }; - -#ifdef RAWNET_DEBUG_ARCH - log_message(rawnet_arch_log, - "rawnet_arch_receive() called, with *plen=%u.", - *plen); -#endif - - assert((*plen & 1) == 0); - - len = rawnet_arch_receive_frame(&internal); - - if (len != -1) { - -#ifdef RAWNET_DEBUG_PKTDUMP - debug_output("Received frame: ", internal.buffer, internal.len); -#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */ - - if (len & 1) { - ++len; - } - - *plen = len; - - /* we don't decide if this frame fits the needs; - * by setting all zero, we let tfe.c do the work - * for us - */ - *phashed = - *phash_index = - *pbroadcast = - *pcorrect_mac = - *pcrc_error = 0; - - /* this frame has been received correctly */ - *prx_ok = 1; - - return 1; - } - - return 0; -} - /** \brief Find default device on which to capture * diff --git a/src/rawnet/rawnetarch_win32.c b/src/rawnet/rawnetarch_win32.c index 741dbce..e6527d1 100644 --- a/src/rawnet/rawnetarch_win32.c +++ b/src/rawnet/rawnetarch_win32.c @@ -438,23 +438,29 @@ static int rawnet_arch_receive_frame(Ethernet_PCAP_internal_t *pinternal) return ret; } -/* int force - FORCE: Delete waiting frames in transmit buffer */ -/* int onecoll - ONECOLL: Terminate after just one collision */ -/* int inhibit_crc - INHIBITCRC: Do not append CRC to the transmission */ -/* int tx_pad_dis - TXPADDIS: Disable padding to 60 Bytes */ -/* int txlength - Frame length */ -/* uint8_t *txframe - Pointer to the frame to be transmitted */ -void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, int tx_pad_dis, int txlength, uint8_t *txframe) -{ -#ifdef RAWNET_DEBUG_ARCH - log_message(rawnet_arch_log, "rawnet_arch_transmit() called, with: force = %s, onecoll = %s, inhibit_crc=%s, tx_pad_dis=%s, txlength=%u", - force ? "TRUE" : "FALSE", - onecoll ? "TRUE" : "FALSE", - inhibit_crc ? "TRUE" : "FALSE", - tx_pad_dis ? "TRUE" : "FALSE", - txlength); -#endif +int rawnet_arch_read(void *buffer, int nbyte) { + + int len; + + Ethernet_PCAP_internal_t internal; + + internal.len = nbyte; + internal.buffer = (uint8_t *)buffer; + + len = rawnet_arch_receive_frame(&internal); + + if (len <= 0) return len; + +#ifdef RAWNET_DEBUG_PKTDUMP + debug_output("Received frame: ", internal.buffer, internal.len); +#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */ + return len; + +} + + +int rawnet_arch_write(const void *buffer, int nbyte) { #ifdef RAWNET_DEBUG_PKTDUMP debug_output("Transmit frame: ", txframe, txlength); @@ -462,9 +468,12 @@ void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, int tx_pad_di if ((*p_pcap_sendpacket)(EthernetPcapFP, txframe, txlength) == -1) { log_message(rawnet_arch_log, "WARNING! Could not send packet!"); + return -1; } + return nbyte; } + /* rawnet_arch_receive()