/* returns packet id */ static u_int32_t print_pkt (struct nfq_data *tb) { int id = 0; struct nfqnl_msg_packet_hdr *ph; u_int32_t mark,ifi; int ret; char *data; ph = nfq_get_msg_packet_hdr(tb); if (ph){ id = ntohl(ph->packet_id); printf("hw_protocol=0x%04x hook=%u id=%u ", ntohs(ph->hw_protocol), ph->hook, id); } mark = nfq_get_nfmark(tb); if (mark) printf("mark=%u ", mark); ifi = nfq_get_indev(tb); if (ifi) printf("indev=%u ", ifi); ifi = nfq_get_outdev(tb); if (ifi) printf("outdev=%u ", ifi); ret = nfq_get_payload(tb, &data); if (ret >= 0) printf("payload_len=%d ", ret); fputc('\n', stdout); return id; }
static u_int32_t fwnfq_process_pkt (struct nfq_data *tb, FWAction *action) { struct nfqnl_msg_packet_hdr *ph; gint id = 0; u_int32_t mark, ifi, ifo, ifaceidx; gint ret, iphdrlen; gchar *data; FWDirection dir; struct ip *hdr; ph = nfq_get_msg_packet_hdr(tb); if ( ph ) { id = ntohl(ph->packet_id); printf("hw_protocol=0x%04x hook=%u id=%u ", ntohs(ph->hw_protocol), ph->hook, id); } mark = nfq_get_nfmark(tb); if ( mark ) printf("mark=%u ", mark); ifi = nfq_get_indev(tb); if ( ifi ) { printf("indev=%u ", ifi-1); dir = DIR_INCOMING; ifaceidx = ifi - 1; } ifo = nfq_get_outdev(tb); if ( ifo ) { printf("outdev=%u ", ifo-1); dir = DIR_OUTGOING; ifaceidx = ifo - 1; } ret = nfq_get_payload(tb, &data); if ( ret >= 0 ) printf("payload_len=%d ", ret); printf("\n\n"); /* Refresh every 50 packet */ // if ( (id % 50) == 0 ) { // fwproc_netentries_process(PROTO_TCP); // fwproc_netentries_process(PROTO_UDP); // fwproc_scan_procdir(); // } hdr = (struct ip *) data; iphdrlen = hdr->ip_hl * 4; // IP header len = ip_hl * 4 (32 bits) printf("*** PACKET PROTOCOL: %s ***\n", TxtProto[hdr->ip_p]); *action = fwnfq_process_rules(ifaceidx, dir, data, id); return id; }
static u_int32_t print_pkt (struct nfq_data *tb) { int id = 0; struct nfqnl_msg_packet_hdr *ph; struct nfqnl_msg_packet_hw *hwph; u_int32_t mark,ifi; int ret; char *data; ph = nfq_get_msg_packet_hdr(tb); if (ph) { id = ntohl(ph->packet_id); printf("hw_protocol=0x%04x hook=%u id=%u ", ntohs(ph->hw_protocol), ph->hook, id); } hwph = nfq_get_packet_hw(tb); if (hwph) { int i, hlen = ntohs(hwph->hw_addrlen); printf("hw_src_addr="); for (i = 0; i < hlen-1; i++) printf("%02x:", hwph->hw_addr[i]); printf("%02x ", hwph->hw_addr[hlen-1]); } mark = nfq_get_nfmark(tb); if (mark) printf("mark=%u ", mark); ifi = nfq_get_indev(tb); if (ifi) printf("indev=%u ", ifi); ifi = nfq_get_outdev(tb); if (ifi) printf("outdev=%u ", ifi); ifi = nfq_get_physindev(tb); if (ifi) printf("physindev=%u ", ifi); ifi = nfq_get_physoutdev(tb); if (ifi) printf("physoutdev=%u ", ifi); ret = nfq_get_payload(tb, &data); if (ret >= 0) { printf("payload_len=%d ", ret); //processPacketData (data, ret); } fputc('\n', stdout); return id; }
void NetherNetlink::getInterfaceInfo(struct nfq_data *nfa, NetherPacket &netherPacket) { if (netherConfig.interfaceInfo) { uint32_t ifi; ifi = nfq_get_outdev(nfa); if (ifi) { nfq_get_outdev_name(nlif, nfa, netherPacket.outdevName); } else { strncpy(netherPacket.outdevName, "(unknown)", IFNAMSIZ); netherPacket.outdevName[IFNAMSIZ-1] = '\0'; } } }
int NFQSetupPkt (Packet *p, struct nfq_q_handle *qh, void *data) { struct nfq_data *tb = (struct nfq_data *)data; int ret; char *pktdata; struct nfqnl_msg_packet_hdr *ph; ph = nfq_get_msg_packet_hdr(tb); if (ph != NULL) { p->nfq_v.id = ntohl(ph->packet_id); //p->nfq_v.hw_protocol = ntohs(p->nfq_v.ph->hw_protocol); p->nfq_v.hw_protocol = ph->hw_protocol; } p->nfq_v.mark = nfq_get_nfmark(tb); if (nfq_config.mode == NFQ_REPEAT_MODE) { if ((nfq_config.mark & nfq_config.mask) == (p->nfq_v.mark & nfq_config.mask)) { int iter = 0; if (already_seen_warning < MAX_ALREADY_TREATED) SCLogInfo("Packet seems already treated by suricata"); already_seen_warning++; do { ret = nfq_set_verdict(qh, p->nfq_v.id, NF_ACCEPT, 0, NULL); } while ((ret < 0) && (iter++ < NFQ_VERDICT_RETRY_TIME)); if (ret < 0) { SCLogWarning(SC_ERR_NFQ_SET_VERDICT, "nfq_set_verdict of %p failed %" PRId32 "", p, ret); } return -1 ; } } p->nfq_v.ifi = nfq_get_indev(tb); p->nfq_v.ifo = nfq_get_outdev(tb); #ifdef NFQ_GET_PAYLOAD_SIGNED ret = nfq_get_payload(tb, &pktdata); #else ret = nfq_get_payload(tb, (unsigned char **) &pktdata); #endif /* NFQ_GET_PAYLOAD_SIGNED */ if (ret > 0) { /* nfq_get_payload returns a pointer to a part of memory * that is not preserved over the lifetime of our packet. * So we need to copy it. */ if (ret > 65536) { /* Will not be able to copy data ! Set length to 0 * to trigger an error in packet decoding. * This is unlikely to happen */ SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "NFQ sent too big packet"); SET_PKT_LEN(p, 0); } else { PacketCopyData(p, (uint8_t *)pktdata, ret); } } else if (ret == -1) { /* unable to get pointer to data, ensure packet length is zero. * This will trigger an error in packet decoding */ SET_PKT_LEN(p, 0); } ret = nfq_get_timestamp(tb, &p->ts); if (ret != 0) { memset (&p->ts, 0, sizeof(struct timeval)); gettimeofday(&p->ts, NULL); } p->datalink = DLT_RAW; return 0; }
int payload_get_outdev(struct payload *self) { return nfq_get_outdev(self->nfad); }
/* returns packet id */ static u_int32_t print_pkt (struct nfq_data *tb) { int id = 0; struct nfqnl_msg_packet_hdr *ph; u_int32_t mark,ifi; int ret; char *nf_packet; ph = nfq_get_msg_packet_hdr(tb); if (ph){ id = ntohl(ph->packet_id); printf("hw_protocol=0x%04x hook=%u id=%u ", ntohs(ph->hw_protocol), ph->hook, id); } mark = nfq_get_nfmark(tb); if (mark) printf("mark=%u ", mark); ifi = nfq_get_indev(tb); if (ifi) printf("indev=%u ", ifi); ifi = nfq_get_outdev(tb); if (ifi) printf("outdev=%u ", ifi); ret = nfq_get_payload(tb, &nf_packet); if ((ret >= 0)){ printf("payload_len=%d bytes", ret); fputc('\n', stdout); } // parse the packet headers struct iphdr *iph = ((struct iphdr *) nf_packet); // Computing IP address translation from 32 bits words to 4*8bits decimal /* NOTE ON THE LENGTHS all lengths used in headers are specified in 32bits words thus, to print the size in bytes, we need to multiply this value by 4 */ // display IP HEADERS : ip.h line 45 // ntohs convert short unsigned int, ntohl do the same for long unsigned int fprintf(stdout, "IP{v=%u; ihl=%u; tos=%u; tot_len=%u; id=%u; ttl=%u; protocol=%u; " ,iph->version, iph->ihl*4, iph->tos, ntohs(iph->tot_len), ntohs(iph->id), iph->ttl, iph->protocol); char *saddr = inet_ntoa(*(struct in_addr *)&iph->saddr); fprintf(stdout,"saddr=%s; ",saddr); char *daddr = inet_ntoa(*(struct in_addr *)&iph->daddr); fprintf(stdout,"daddr=%s}\n",daddr); // if protocol is tcp if (iph->protocol == 6){ // extract tcp header from packet /* Calculate the size of the IP Header. iph->ihl contains the number of 32 bit words that represent the header size. Therfore to get the number of bytes multiple this number by 4 */ struct tcphdr *tcp = ((struct tcphdr *) (nf_packet + (iph->ihl << 2))); /* Calculate the size of the TCP Header. tcp->doff contains the number of 32 bit words that represent the header size. Therfore to get the number of bytes multiple this number by 4 */ //int tcphdr_size = (tcp->doff << 2); /* to print the TCP headers, we access the structure defined in tcp.h line 89 and convert values from hexadecimal to ascii */ fprintf(stdout, "TCP{sport=%u; dport=%u; seq=%u; ack_seq=%u; flags=u%ua%up%ur%us%uf%u; window=%u; urg=%u}\n", ntohs(tcp->source), ntohs(tcp->dest), ntohl(tcp->seq), ntohl(tcp->ack_seq) ,tcp->urg, tcp->ack, tcp->psh, tcp->rst, tcp->syn, tcp->fin, ntohs(tcp->window), tcp->urg_ptr); } // if protocol is udp if(iph->protocol == 17){ struct udphdr *udp = ((struct udphdr *) (nf_packet + (iph->ihl << 2))); fprintf(stdout,"UDP{sport=%u; dport=%u; len=%u}\n", ntohs(udp->source), ntohs(udp->dest), udp->len); } fprintf(stdout,"\n"); return id; }
static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) { //log_debug("entering callback"); //char buf[1025]; //nfq_snprintf_xml(buf, 1024, nfa, NFQ_XML_ALL); //log_debug("%s", buf); struct nfqnl_msg_packet_hdr *ph; ph = nfq_get_msg_packet_hdr(nfa); if (!ph) { log_error("nfq_get_msg_packet_hdr failed"); return -1; } u_int32_t id = ntohl(ph->packet_id); //log_debug("packet id: %d", id); char inout = nfq_get_outdev(nfa) ? 1 : 0; // 0 - in, 1 - out // get data (IP header + TCP header + payload) unsigned char *pkt_data; int plen = nfq_get_payload(nfa, &pkt_data); g_modified = 0; //if (plen >= 0) // log_debug("payload_len=%d", plen); //hex_dump(pkt_data, plen); struct mypacket packet; packet.data = pkt_data; packet.len = plen; packet.iphdr = ip_hdr(pkt_data); // parse ip //char sip[16], dip[16]; //ip2str(packet.iphdr->saddr, sip); //ip2str(packet.iphdr->daddr, dip); //log_debug("This packet goes from %s to %s.", sip, dip); //log_debugv("This packet goes from %s to %s.", sip, dip); if (is_ip_in_whitelist(packet.iphdr->saddr) || is_ip_in_whitelist(packet.iphdr->daddr)) { nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL); return 0; } int ret = 0; switch (packet.iphdr->protocol) { case 6: // TCP packet.tcphdr = tcp_hdr(pkt_data); packet.payload = tcp_payload(pkt_data); packet.payload_len = packet.len - packet.iphdr->ihl*4 - packet.tcphdr->th_off*4; //show_packet(&packet); ret = process_tcp_packet(&packet, inout); break; case 17: // UDP packet.udphdr = udp_hdr(pkt_data); packet.payload = udp_payload(pkt_data); packet.payload_len = packet.len - packet.iphdr->ihl*4 - 8; if (packet.payload_len != ntohs(packet.udphdr->uh_ulen) - 8) log_warn("UDP payload length unmatch! %d <> %d", packet.payload_len, ntohs(packet.udphdr->uh_ulen) - 8); //show_packet(&packet); ret = process_udp_packet(&packet, inout); break; default: log_error("Invalid protocol: %d", packet.iphdr->protocol); } int verdict_ret; if (ret == 0) { if (g_modified) { log_warn("Packet Modified."); //if (packet.iphdr->protocol == 6) { // packet.tcphdr->th_sum = tcp_checksum(packet.data, ntohs(packet.iphdr->tot_len)); //} //packet.iphdr->check = ip_checksum(packet.data, packet.len); verdict_ret = nfq_set_verdict(qh, id, NF_ACCEPT, packet.len, packet.data); //log_info("VERDICT MODIFIED ACCEPT"); } else { verdict_ret = nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL); //log_info("VERDICT ACCEPT"); } } else if (ret == 1) { usleep(DELAY_AFTER_PACKET_INJECTION); verdict_ret = nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL); //log_info("VERDICT DELAYED ACCEPT"); } else { verdict_ret = nfq_set_verdict(qh, id, NF_DROP, 0, NULL); //log_info("VERDICT DROP"); } // return <0 to stop processing return verdict_ret; }