#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <net/ethernet.h>
+#include <zlib.h>
#include <arpa/inet.h>
#include "inm-manager-log.h"
#include "inm-error-analysis.h"
-#define ARP_PACKET_SIZE 60
+#define ARP_FRAME_SIZE 64
+#define ETHERNET_FCS_SIZE 4
#ifndef MAC_FMT
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
static void __arp_sock_io_in(GIOChannel *source, inm_util_arp_data_s *arp_data)
{
arp_message_s *ah = NULL;
- gchar buf[ARP_PACKET_SIZE] = {0, };
+ gchar buf[ARP_FRAME_SIZE] = {0, };
gchar *ptr = NULL;
gsize bytes_read = 0;
GError *error = NULL;
INM_LOGI("Read channel");
- if (g_io_channel_read_chars(source, buf, ARP_PACKET_SIZE,
+ if (g_io_channel_read_chars(source, buf, ARP_FRAME_SIZE,
&bytes_read, &error) != G_IO_STATUS_NORMAL) {
if (error) {
INM_LOGE("Failure received arp packet[%d]:[%s]",
return;
}
+static void __set_ethernet_fcs(guchar *p_frame)
+{
+ uint32_t eth_frame_fcs;
+ int pos;
+
+ if (!p_frame) {
+ return;
+ }
+
+ for (pos = 8; pos < ARP_FRAME_SIZE; pos += 8) {
+ eth_frame_fcs = crc32(0, Z_NULL, 0);
+ eth_frame_fcs = crc32(eth_frame_fcs, (const unsigned char *)p_frame, pos);
+ }
+
+ eth_frame_fcs = crc32(0, Z_NULL, 0);
+ eth_frame_fcs = crc32(eth_frame_fcs, (const unsigned char *)p_frame,
+ (ARP_FRAME_SIZE - ETHERNET_FCS_SIZE));
+ memcpy(p_frame + (ARP_FRAME_SIZE - ETHERNET_FCS_SIZE),
+ ð_frame_fcs, sizeof(uint32_t));
+}
+
int util_recover_arp_sock(inm_util_arp_data_s *arp_data)
{
__INM_FUNC_ENTER__;
{
inm_util_arp_data_s *arp_data = (inm_util_arp_data_s *)user_data;
struct sockaddr_ll ll_addr;
- guchar buf[64] = {0,};
+ guchar buf[ARP_FRAME_SIZE] = {0,};
guchar *pos = NULL;
gint ret = 0;
char err_str[128] = {0,};
return FALSE;
if (!IS_ZERO_IP(arp_data->target_ip_addr))
- memcpy(arp_data->ipaddr, arp_data->target_ip_addr, 4);
+ memcpy(arp_data->ipaddr, arp_data->target_ip_addr, IP_ALEN);
/* tweak
arp_data->ipaddr[3] = 120;
*/
memcpy(ll_addr.sll_addr, arp_data->hwaddr, ETH_ALEN);
ll_addr.sll_ifindex = arp_data->ifindex;
+ __set_ethernet_fcs(buf);
+
ret = sendto(arp_data->sock, buf, sizeof(buf), 0,
(struct sockaddr *) &(ll_addr),
sizeof(struct sockaddr_ll));