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 
39 EXPORT_SYMBOL
40 struct 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 
72 EXPORT_SYMBOL
73 int 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 
101 EXPORT_SYMBOL
102 void 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 
126 EXPORT_SYMBOL
127 int 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);
139  nfq_ip_set_checksum(iph);
140 
141  return 1;
142 }
143 
152 EXPORT_SYMBOL
153 int 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 
int nfq_ip_set_transport_header(struct pkt_buff *pktb, struct iphdr *iph)
Definition: ipv4.c:73
struct iphdr * nfq_ip_get_hdr(struct pkt_buff *pktb)
Definition: ipv4.c:40
void nfq_ip_set_checksum(struct iphdr *iph)
Definition: ipv4.c:102
int nfq_ip_snprintf(char *buf, size_t size, const struct iphdr *iph)
Definition: ipv4.c:153
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
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