bool sinsp_filter_check_fd::compare(sinsp_evt *evt) { // // A couple of fields are filter only and therefore get a special treatment // if(m_field_id == TYPE_IP) { return compare_ip(evt); } else if(m_field_id == TYPE_PORT) { return compare_port(evt); } // // Standard extract-based fields // uint32_t len; uint8_t* extracted_val = extract(evt, &len); if(extracted_val == NULL) { return false; } return flt_compare(m_cmpop, m_info.m_fields[m_field_id].m_type, extracted_val, &m_val_storage[0]); }
// PURPOSE // // Determine destination MAC address to provide direct or indirect // delivery of IP packets, depending on which is appropriate. // // Doing this, the caller must provide // 1) A pointer to the interface (within the device_list) // 2) The destination IP address // 3) A pointer to the destination MAC address // // If a Class D (multicast) address is given, a proper IEEE multicast MAC // address is derived. // // EXAMPLE // // u_int8_t ip[4], // mac[6]; // // mops_hton4 (mp->ip_src, ip); // // mops_ip_get_dst_mac(&device_list[0], ip, mac); // // RETURN VALUES // // 0 upon success // 1 upon error // int mops_ip_get_dst_mac(struct device_struct *dev, u_int8_t *ip, u_int8_t *mac) { int i; u_int8_t dst_net[4]; if ((dev==NULL)||(ip==NULL)||(mac==NULL)) return 1; // Multicast address? if ((0xe0 & ip[0]) == 0xe0) { mac[0] = 0x01; mac[1] = 0x00; mac[2] = 0x5e; mac[3] = ip[1] & 127; mac[4] = ip[2]; mac[5] = ip[3]; return 0; } // Is destination network == local network? for (i=0; i<4; i++) { dst_net[i] = ip[i] & (u_int8_t) dev->mask[i]; } if (compare_ip(dst_net, dev->net)==0) { // dst is on local LAN => resolve MAC! service_arp(dev->dev, ip, mac); } else { // dst is on a remote network => use default gw! for (i=0; i<6; i++) mac[i] = dev->mac_gw[i]; } return 0; }
// Add new entry in device-specific ARP table // but first check if already existing or change. // // RETURN VALUE: 0 upon success // 1 upon error // int arptable_add(struct device_struct *dev, u_int8_t *sa, u_int8_t *da, u_int8_t *smac, u_int8_t *sip, u_int32_t sec, u_int32_t nsec) { struct arp_table_struct *prev=NULL, *cur = dev->arp_table; int i=0, alert=0; // If SA and SMAC are different this might be a MITM !!! if (compare_mac(smac, sa)) alert=1; // Check if IP (sip) is already existing in arp table: while (cur!=NULL) { if (compare_ip(sip, cur->sip)==0) { // IP found! timestamp_hms(cur->when); if (da[0]==0xff) cur->bc_resp++; else cur->uni_resp++; if (compare_mac(smac, cur->smac)==0) { // entry identical ! cur->sec=sec; cur->nsec=nsec; return 0; } else { // entry with other MAC address found ! if (cur->locked==0) { cur->changed++; memcpy((void*) cur->smac_prev, (void*) cur->smac, 6); memcpy((void*) cur->smac, (void*) smac, 6); cur->sec_prev=cur->sec; cur->nsec_prev=cur->nsec; cur->sec=sec; cur->nsec=nsec; if (alert) cur->flags|=0x02; } return 0; } } prev = cur; cur = cur->next; i++; } // If we get here, then there was no entry for that IP yet! // Create new arp_table entry: cur = (struct arp_table_struct *) malloc(sizeof(struct arp_table_struct)); if (cur==NULL) return 1; // Append element: if (dev->arp_table==NULL) dev->arp_table = cur; else prev->next = cur; memcpy((void*) cur->sa, (void*) sa, 6); memcpy((void*) cur->smac, (void*) smac, 6); cur->smac_prev[0]=0x00; cur->smac_prev[1]=0x00; cur->smac_prev[2]=0x00; cur->smac_prev[3]=0x00; cur->smac_prev[4]=0x00; cur->smac_prev[5]=0x00; memcpy((void*) cur->sip, (void*) sip, 4); if (da[0]==0xff) { cur->bc_resp=1; cur->uni_resp=0; } else { cur->bc_resp=0; cur->uni_resp=1; } cur->changed=1; cur->locked=0; cur->dynamic=1; cur->flags=0; cur->sec=sec; cur->nsec=nsec; cur->sec_prev=0; cur->nsec_prev=0; cur->index=i+1; // I assume users prefer to count from 1. timestamp_hms(cur->when); if (alert) cur->flags|=0x02; cur->next=NULL; return 0; }
/** * Netfilter hook function for incoming packets * */ unsigned int in_hook_func(unsigned int hooknum, struct sk_buff* skb, const struct net_device* in, const struct net_device* out, int (*okfn)(struct sk_buff* )) { int i; sock_buff = skb; /* Extract network header using accessor */ ip_header = (struct iphdr* )skb_network_header(sock_buff); udp_header = (struct udphdr* )skb_transport_header(sock_buff); tcp_header = (struct udphdr* )skb_transport_header(sock_buff); if(!sock_buff) { return NF_ACCEPT;} /* Iterate through the T_RULES array */ for(i=0;i<ruleCount;i++) { /* Check if the rule is for incoming packets */ if(T_RULES[i].pkt == 1) { /* Check if the rule has protocol field set to ALL */ if(T_RULES[i].proto == 0 ) { /* Check IP address */ if(compare_ip((unsigned int)ip_header->saddr, T_RULES[i].srcip)) { /* Check destination port number */ if(compare_port(tcp_header->dest, T_RULES[i].dstpt)) { /* Check whether to BLOCK the packet */ if(T_RULES[i].block == 1) { printk(KERN_INFO"firewall: Blocking incoming pkts\n"); return NF_DROP; } else { if(T_RULES[i].block == 0) { printk(KERN_INFO"firewall: Unblocking incoming pkts"); return NF_ACCEPT; } } } } } /* Check if the rule has protocol field set to TCP */ if((T_RULES[i].proto == 1) && (ip_header->protocol == 6)){ /* Check IP address */ if(compare_ip((unsigned int)ip_header->saddr, T_RULES[i].srcip)) { /* Check destination port number */ if(compare_port(tcp_header->dest, T_RULES[i].dstpt)) { /* Check whether to BLOCK the packet */ if(T_RULES[i].block == 1) { printk(KERN_INFO"firewall: Blocking Incoming TCP pkts\n"); return NF_DROP; } else { if(T_RULES[i].block == 0) { printk(KERN_INFO"firewall: Unblocking Incoming TCP pkts"); return NF_ACCEPT; } } } } } /* Check if the rule has protocol field set to UDP */ if((T_RULES[i].proto == 2) && (ip_header->protocol == 17)) { /* Check IP address */ if(compare_ip((unsigned int)ip_header->saddr, T_RULES[i].srcip)) { /* Check destination port number */ if(compare_port(tcp_header->dest, T_RULES[i].dstpt)) { /* Check whether to BLOCK the packet */ if(T_RULES[i].block == 1) { printk(KERN_INFO"firewall: Blocking Incoming UDP pkts\n"); return NF_DROP; } else { if(T_RULES[i].block == 0) { printk(KERN_INFO"firewall: Unblocking all Incoming UDP pkts"); return NF_ACCEPT; } } } } } } } return NF_ACCEPT; }