struct iphdr *nfq_ip_get_hdr(struct pkt_buff *pktb);
int nfq_ip_set_transport_header(struct pkt_buff *pktb, struct iphdr *iph);
void nfq_ip_set_checksum(struct iphdr *iph);
+int nfq_ip_mangle(struct pkt_buff *pkt, unsigned int dataoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
int nfq_ip_snprintf(char *buf, size_t size, const struct iphdr *iph);
#endif
void nfq_tcp_compute_checksum_ipv4(struct tcphdr *tcph, struct iphdr *iph);
void nfq_tcp_compute_checksum_ipv6(struct tcphdr *tcph, struct ip6_hdr *ip6h);
+int nfq_tcp_mangle_ipv4(struct pkt_buff *pkt, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
+
int nfq_tcp_snprintf(char *buf, size_t size, const struct tcphdr *tcp);
#endif
void nfq_udp_compute_checksum_ipv4(struct udphdr *udph, struct iphdr *iph);
void nfq_udp_compute_checksum_ipv6(struct udphdr *udph, struct ip6_hdr *ip6h);
+int nfq_udp_mangle_ipv4(struct pkt_buff *pkt, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
+
int nfq_udp_snprintf(char *buf, size_t size, const struct udphdr *udp);
#endif
uint8_t *pktb_network_header(struct pkt_buff *pktb);
uint8_t *pktb_transport_header(struct pkt_buff *pktb);
+int pktb_mangle(struct pkt_buff *pkt, unsigned int dataoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
+
+bool pktb_mangled(const struct pkt_buff *pktb);
+
#endif
*/
#include <stdio.h>
+#include <stdbool.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
*/
#include <stdio.h>
+#include <stdbool.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
}
EXPORT_SYMBOL(nfq_ip_set_checksum);
+int nfq_ip_mangle(struct pkt_buff *pkt, unsigned int dataoff,
+ unsigned int match_offset, unsigned int match_len,
+ const char *rep_buffer, unsigned int rep_len)
+{
+ struct iphdr *iph = (struct iphdr *) pkt->network_header;
+
+ if (!pktb_mangle(pkt, dataoff, match_offset, match_len,
+ rep_buffer, rep_len))
+ return 0;
+
+ /* fix IP hdr checksum information */
+ iph->tot_len = htons(pkt->len);
+ nfq_ip_set_checksum(iph);
+
+ return 1;
+}
+EXPORT_SYMBOL(nfq_ip_mangle);
+
/**
* nfq_pkt_snprintf_ip - print IPv4 header into buffer in iptables LOG format
* \param buf: pointer to buffer that will be used to print the header
#include <stdio.h>
#include <stddef.h>
+#include <stdbool.h>
#include <arpa/inet.h>
#include <netinet/ip6.h>
#include <stdlib.h>
#include <string.h> /* for memcpy */
+#include <stdbool.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
return pktb->transport_header;
}
+static int pktb_expand_tail(struct pkt_buff *pkt, int extra)
+{
+ /* XXX: support reallocation case. */
+ pkt->len += extra;
+ pkt->tail = pkt->tail + extra;
+ return 0;
+}
+
+static int enlarge_pkt(struct pkt_buff *pkt, unsigned int extra)
+{
+ if (pkt->len + extra > 65535)
+ return 0;
+
+ if (pktb_expand_tail(pkt, extra - pktb_tailroom(pkt)))
+ return 0;
+
+ return 1;
+}
+
+int pktb_mangle(struct pkt_buff *pkt,
+ unsigned int dataoff,
+ unsigned int match_offset,
+ unsigned int match_len,
+ const char *rep_buffer,
+ unsigned int rep_len)
+{
+ unsigned char *data;
+
+ if (rep_len > match_len &&
+ rep_len - match_len > pktb_tailroom(pkt) &&
+ !enlarge_pkt(pkt, rep_len - match_len))
+ return 0;
+
+ data = pkt->network_header + dataoff;
+
+ /* move post-replacement */
+ memmove(data + match_offset + rep_len,
+ data + match_offset + match_len,
+ pkt->tail - (pkt->network_header + dataoff +
+ match_offset + match_len));
+
+ /* insert data from buffer */
+ memcpy(data + match_offset, rep_buffer, rep_len);
+
+ /* update pkt info */
+ if (rep_len > match_len)
+ pktb_put(pkt, rep_len - match_len);
+ else
+ pktb_trim(pkt, pkt->len + rep_len - match_len);
+
+ pkt->mangled = true;
+ return 1;
+}
+EXPORT_SYMBOL(pktb_mangle);
+
+bool pktb_mangled(const struct pkt_buff *pkt)
+{
+ return pkt->mangled;
+}
+EXPORT_SYMBOL(pktb_mangled);
+
/**
* @}
*/
#include <stdio.h>
#include <string.h> /* for memcpy */
+#include <stdbool.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <libnetfilter_queue/libnetfilter_queue.h>
#include <libnetfilter_queue/libnetfilter_queue_tcp.h>
+#include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
#include <libnetfilter_queue/pktbuff.h>
#include "internal.h"
#define TCP_RESERVED_BITS htonl(0x0F000000)
ret = snprintf(buf, size, "SPT=%u DPT=%u SEQ=%u ACK=%u "
- "WINDOW=%u RES=%0x%02x ",
+ "WINDOW=%u RES=0x%02x ",
ntohs(tcph->source), ntohs(tcph->dest),
ntohl(tcph->seq), ntohl(tcph->ack_seq),
ntohs(tcph->window),
- (uint8_t)(ntohl(tcp_flag_word(tcph) &
- TCP_RESERVED_BITS) >> 22));
+ (uint8_t)
+ (ntohl(tcp_flag_word(tcph) & TCP_RESERVED_BITS) >> 22));
len += ret;
if (tcph->urg) {
ret = snprintf(buf+len, size-len, "FIN ");
len += ret;
}
- /* Not TCP options implemented yet, sorry. */
+ /* XXX: Not TCP options implemented yet, sorry. */
+
+ return ret;
}
EXPORT_SYMBOL(nfq_tcp_snprintf);
+int
+nfq_tcp_mangle_ipv4(struct pkt_buff *pkt,
+ unsigned int match_offset, unsigned int match_len,
+ const char *rep_buffer, unsigned int rep_len)
+{
+ struct iphdr *iph;
+ struct tcphdr *tcph;
+
+ iph = (struct iphdr *)pkt->network_header;
+ tcph = (struct tcphdr *)(pkt->network_header + iph->ihl*4);
+
+ if (!nfq_ip_mangle(pkt, iph->ihl*4 + tcph->doff*4,
+ match_offset, match_len, rep_buffer, rep_len))
+ return 0;
+
+ nfq_tcp_compute_checksum_ipv4(tcph, iph);
+
+ return 1;
+}
+EXPORT_SYMBOL(nfq_tcp_mangle_ipv4);
+
/**
* @}
*/
*/
#include <stdio.h>
+#include <stdbool.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <libnetfilter_queue/libnetfilter_queue.h>
#include <libnetfilter_queue/libnetfilter_queue_udp.h>
+#include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
#include <libnetfilter_queue/pktbuff.h>
#include "internal.h"
}
EXPORT_SYMBOL(nfq_udp_compute_checksum_ipv6);
+int
+nfq_udp_mangle_ipv4(struct pkt_buff *pkt,
+ unsigned int match_offset, unsigned int match_len,
+ const char *rep_buffer, unsigned int rep_len)
+{
+ struct iphdr *iph;
+ struct udphdr *udph;
+
+ iph = (struct iphdr *)pkt->network_header;
+ udph = (struct udphdr *)(pkt->network_header + iph->ihl*4);
+
+ if (!nfq_ip_mangle(pkt, iph->ihl*4 + sizeof(struct udphdr),
+ match_offset, match_len, rep_buffer, rep_len))
+ return 0;
+
+ nfq_udp_compute_checksum_ipv4(udph, iph);
+
+ return 1;
+}
+EXPORT_SYMBOL(nfq_udp_mangle_ipv4);
+
/**
* nfq_pkt_snprintf_udp_hdr - print udp header into one buffer in a humnan
* readable way
uint32_t len;
uint32_t data_len;
+
+ bool mangled;
};
#endif