libnetfilter_queue 1.0.5
ipv4.c
1/*
2 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
10 */
11
12#include <stdio.h>
13#include <stdbool.h>
14#include <arpa/inet.h>
15#include <netinet/ip.h>
16
17#include <libnetfilter_queue/libnetfilter_queue.h>
18#include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
19#include <libnetfilter_queue/pktbuff.h>
20
21#include "internal.h"
22
39EXPORT_SYMBOL
40struct iphdr *nfq_ip_get_hdr(struct pkt_buff *pktb)
41{
42 struct iphdr *iph;
43 unsigned int pktlen = pktb_tail(pktb) - pktb->network_header;
44
45 /* Not enough room for IPv4 header. */
46 if (pktlen < sizeof(struct iphdr))
47 return NULL;
48
49 iph = (struct iphdr *)pktb->network_header;
50
51 /* Not IPv4 packet. */
52 if (iph->version != 4)
53 return NULL;
54
55 /* Malformed IPv4 total length field. */
56 if (ntohs(iph->tot_len) > pktlen)
57 return NULL;
58
59 return iph;
60}
61
72EXPORT_SYMBOL
73int nfq_ip_set_transport_header(struct pkt_buff *pktb, struct iphdr *iph)
74{
75 int doff = iph->ihl * 4;
76
77 /* Wrong offset to IPv4 payload. */
78 if ((int)pktb->len - doff <= 0)
79 return -1;
80
81 pktb->transport_header = pktb->network_header + doff;
82 return 0;
83}
84
101EXPORT_SYMBOL
102void nfq_ip_set_checksum(struct iphdr *iph)
103{
104 uint32_t iph_len = iph->ihl * 4;
105
106 iph->check = 0;
107 iph->check = nfq_checksum(0, (uint16_t *)iph, iph_len);
108}
109
126EXPORT_SYMBOL
127int nfq_ip_mangle(struct pkt_buff *pktb, unsigned int dataoff,
128 unsigned int match_offset, unsigned int match_len,
129 const char *rep_buffer, unsigned int rep_len)
130{
131 struct iphdr *iph = (struct iphdr *) pktb->network_header;
132
133 if (!pktb_mangle(pktb, dataoff, match_offset, match_len, rep_buffer,
134 rep_len))
135 return 0;
136
137 /* fix IP hdr checksum information */
138 iph->tot_len = htons(pktb_tail(pktb) - pktb->network_header);
140
141 return 1;
142}
143
152EXPORT_SYMBOL
153int nfq_ip_snprintf(char *buf, size_t size, const struct iphdr *iph)
154{
155 int ret;
156 struct in_addr src = { iph->saddr };
157 struct in_addr dst = { iph->daddr };
158
159 char src_str[INET_ADDRSTRLEN];
160 char dst_str[INET_ADDRSTRLEN];
161
162 ret = snprintf(buf, size, "SRC=%s DST=%s LEN=%u TOS=0x%X "
163 "PREC=0x%X TTL=%u ID=%u PROTO=%u ",
164 inet_ntop(AF_INET, &src, src_str, INET_ADDRSTRLEN),
165 inet_ntop(AF_INET, &dst, dst_str, INET_ADDRSTRLEN),
166 ntohs(iph->tot_len), IPTOS_TOS(iph->tos),
167 IPTOS_PREC(iph->tos), iph->ttl, ntohs(iph->id),
168 iph->protocol);
169
170 return ret;
171}
172
void nfq_ip_set_checksum(struct iphdr *iph)
Definition: ipv4.c:102
struct iphdr * nfq_ip_get_hdr(struct pkt_buff *pktb)
Definition: ipv4.c:40
int nfq_ip_mangle(struct pkt_buff *pktb, unsigned int dataoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len)
Definition: ipv4.c:127
int nfq_ip_snprintf(char *buf, size_t size, const struct iphdr *iph)
Definition: ipv4.c:153
int nfq_ip_set_transport_header(struct pkt_buff *pktb, struct iphdr *iph)
Definition: ipv4.c:73
int pktb_mangle(struct pkt_buff *pktb, int dataoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len)
Definition: pktbuff.c:314