1/* 2 * This is a module which is used for rejecting packets. 3 * Added support for customized reject packets (Jozsef Kadlecsik). 4 */ 5#include <linux/config.h> 6#include <linux/module.h> 7#include <linux/skbuff.h> 8#include <linux/ip.h> 9#include <linux/udp.h> 10#include <linux/icmp.h> 11#include <net/icmp.h> 12#include <net/ip.h> 13#include <net/tcp.h> 14struct in_device; 15#include <net/route.h> 16#include <linux/netfilter_ipv4/ip_tables.h> 17#include <linux/netfilter_ipv4/ipt_REJECT.h> 18 19#define DEBUGP(format, args...) 20 21/* If the original packet is part of a connection, but the connection 22 is not confirmed, our manufactured reply will not be associated 23 with it, so we need to do this manually. */ 24static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct) 25{ 26 void (*attach)(struct sk_buff *, struct nf_ct_info *); 27 28 /* Avoid module unload race with ip_ct_attach being NULLed out */ 29 if (nfct && (attach = ip_ct_attach) != NULL) 30 attach(new_skb, nfct); 31} 32 33/* Send RST reply */ 34static void send_reset(struct sk_buff *oldskb, int local) 35{ 36 struct sk_buff *nskb; 37 struct tcphdr *otcph, *tcph; 38 struct rtable *rt; 39 unsigned int otcplen; 40 u_int16_t tmp_port; 41 u_int32_t tmp_addr; 42 int needs_ack; 43 44 /* IP header checks: fragment, too short. */ 45 if (oldskb->nh.iph->frag_off & htons(IP_OFFSET) 46 || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr)) 47 return; 48 49 otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl); 50 otcplen = oldskb->len - oldskb->nh.iph->ihl*4; 51 52 /* No RST for RST. */ 53 if (otcph->rst) 54 return; 55 56 /* Check checksum. */ 57 if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr, 58 oldskb->nh.iph->daddr, 59 csum_partial((char *)otcph, otcplen, 0)) != 0) 60 return; 61 62 /* Copy skb (even if skb is about to be dropped, we can't just 63 clone it because there may be other things, such as tcpdump, 64 interested in it) */ 65 nskb = skb_copy(oldskb, GFP_ATOMIC); 66 if (!nskb) 67 return; 68 69 /* This packet will not be the same as the other: clear nf fields */ 70 nf_conntrack_put(nskb->nfct); 71 nskb->nfct = NULL; 72 nskb->nfcache = 0; 73#ifdef CONFIG_NETFILTER_DEBUG 74 nskb->nf_debug = 0; 75#endif 76 nskb->nfmark = 0; 77 78 tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl); 79 80 /* Swap source and dest */ 81 tmp_addr = nskb->nh.iph->saddr; 82 nskb->nh.iph->saddr = nskb->nh.iph->daddr; 83 nskb->nh.iph->daddr = tmp_addr; 84 tmp_port = tcph->source; 85 tcph->source = tcph->dest; 86 tcph->dest = tmp_port; 87 88 /* Truncate to length (no data) */ 89 tcph->doff = sizeof(struct tcphdr)/4; 90 skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr)); 91 nskb->nh.iph->tot_len = htons(nskb->len); 92 93 if (tcph->ack) { 94 needs_ack = 0; 95 tcph->seq = otcph->ack_seq; 96 tcph->ack_seq = 0; 97 } else { 98 needs_ack = 1; 99 tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin 100 + otcplen - (otcph->doff<<2)); 101 tcph->seq = 0; 102 } 103 104 /* Reset flags */ 105 ((u_int8_t *)tcph)[13] = 0; 106 tcph->rst = 1; 107 tcph->ack = needs_ack; 108 109 tcph->window = 0; 110 tcph->urg_ptr = 0; 111 112 /* Adjust TCP checksum */ 113 tcph->check = 0; 114 tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), 115 nskb->nh.iph->saddr, 116 nskb->nh.iph->daddr, 117 csum_partial((char *)tcph, 118 sizeof(struct tcphdr), 0)); 119 120 /* Adjust IP TTL, DF */ 121 nskb->nh.iph->ttl = MAXTTL; 122 /* Set DF, id = 0 */ 123 nskb->nh.iph->frag_off = htons(IP_DF); 124 nskb->nh.iph->id = 0; 125 126 /* Adjust IP checksum */ 127 nskb->nh.iph->check = 0; 128 nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph, 129 nskb->nh.iph->ihl); 130 131 /* Routing: if not headed for us, route won't like source */ 132 if (ip_route_output(&rt, nskb->nh.iph->daddr, 133 local ? nskb->nh.iph->saddr : 0, 134 RT_TOS(nskb->nh.iph->tos) | RTO_CONN, 135 0) != 0) 136 goto free_nskb; 137 138 dst_release(nskb->dst); 139 nskb->dst = &rt->u.dst; 140 141 /* "Never happens" */ 142 if (nskb->len > nskb->dst->pmtu) 143 goto free_nskb; 144 145 connection_attach(nskb, oldskb->nfct); 146 147 NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev, 148 ip_finish_output); 149 return; 150 151 free_nskb: 152 kfree_skb(nskb); 153} 154 155static void send_unreach(struct sk_buff *skb_in, int code) 156{ 157 struct iphdr *iph; 158 struct udphdr *udph; 159 struct icmphdr *icmph; 160 struct sk_buff *nskb; 161 u32 saddr; 162 u8 tos; 163 int hh_len, length; 164 struct rtable *rt = (struct rtable*)skb_in->dst; 165 unsigned char *data; 166 167 if (!rt) 168 return; 169 170 if (!xrlim_allow(&rt->u.dst, 1*HZ)) 171 return; 172 173 iph = skb_in->nh.iph; 174 175 /* No replies to physical multicast/broadcast */ 176 if (skb_in->pkt_type!=PACKET_HOST) 177 return; 178 179 /* Now check at the protocol level */ 180 if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST)) 181 return; 182 183 /* Only reply to fragment 0. */ 184 if (iph->frag_off&htons(IP_OFFSET)) 185 return; 186 187 /* if UDP checksum is set, verify it's correct */ 188 if (iph->protocol == IPPROTO_UDP 189 && skb_in->tail-(u8*)iph >= sizeof(struct udphdr)) { 190 int datalen = skb_in->len - (iph->ihl<<2); 191 udph = (struct udphdr *)((char *)iph + (iph->ihl<<2)); 192 if (udph->check 193 && csum_tcpudp_magic(iph->saddr, iph->daddr, 194 datalen, IPPROTO_UDP, 195 csum_partial((char *)udph, datalen, 196 0)) != 0) 197 return; 198 } 199 200 /* If we send an ICMP error to an ICMP error a mess would result.. */ 201 if (iph->protocol == IPPROTO_ICMP 202 && skb_in->tail-(u8*)iph >= sizeof(struct icmphdr)) { 203 icmph = (struct icmphdr *)((char *)iph + (iph->ihl<<2)); 204 /* Between echo-reply (0) and timestamp (13), 205 everything except echo-request (8) is an error. 206 Also, anything greater than NR_ICMP_TYPES is 207 unknown, and hence should be treated as an error... */ 208 if ((icmph->type < ICMP_TIMESTAMP 209 && icmph->type != ICMP_ECHOREPLY 210 && icmph->type != ICMP_ECHO) 211 || icmph->type > NR_ICMP_TYPES) 212 return; 213 } 214 215 saddr = iph->daddr; 216 if (!(rt->rt_flags & RTCF_LOCAL)) 217 saddr = 0; 218 219 tos = (iph->tos & IPTOS_TOS_MASK) | IPTOS_PREC_INTERNETCONTROL; 220 221 if (ip_route_output(&rt, iph->saddr, saddr, RT_TOS(tos), 0)) 222 return; 223 224 /* RFC says return as much as we can without exceeding 576 bytes. */ 225 length = skb_in->len + sizeof(struct iphdr) + sizeof(struct icmphdr); 226 227 if (length > rt->u.dst.pmtu) 228 length = rt->u.dst.pmtu; 229 if (length > 576) 230 length = 576; 231 232 hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15; 233 234 nskb = alloc_skb(hh_len+15+length, GFP_ATOMIC); 235 if (!nskb) { 236 ip_rt_put(rt); 237 return; 238 } 239 240 nskb->priority = 0; 241 nskb->dst = &rt->u.dst; 242 skb_reserve(nskb, hh_len); 243 244 /* Set up IP header */ 245 iph = nskb->nh.iph 246 = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr)); 247 iph->version=4; 248 iph->ihl=5; 249 iph->tos=tos; 250 iph->tot_len = htons(length); 251 252 /* PMTU discovery never applies to ICMP packets. */ 253 iph->frag_off = 0; 254 255 iph->ttl = MAXTTL; 256 ip_select_ident(iph, &rt->u.dst, NULL); 257 iph->protocol=IPPROTO_ICMP; 258 iph->saddr=rt->rt_src; 259 iph->daddr=rt->rt_dst; 260 iph->check=0; 261 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); 262 263 /* Set up ICMP header. */ 264 icmph = nskb->h.icmph 265 = (struct icmphdr *)skb_put(nskb, sizeof(struct icmphdr)); 266 icmph->type = ICMP_DEST_UNREACH; 267 icmph->code = code; 268 icmph->un.gateway = 0; 269 icmph->checksum = 0; 270 271 /* Copy as much of original packet as will fit */ 272 data = skb_put(nskb, 273 length - sizeof(struct iphdr) - sizeof(struct icmphdr)); 274 memcpy(data, skb_in->nh.iph, 275 length - sizeof(struct iphdr) - sizeof(struct icmphdr)); 276 icmph->checksum = ip_compute_csum((unsigned char *)icmph, 277 length - sizeof(struct iphdr)); 278 279 connection_attach(nskb, skb_in->nfct); 280 281 NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev, 282 ip_finish_output); 283} 284 285static unsigned int reject(struct sk_buff **pskb, 286 unsigned int hooknum, 287 const struct net_device *in, 288 const struct net_device *out, 289 const void *targinfo, 290 void *userinfo) 291{ 292 const struct ipt_reject_info *reject = targinfo; 293 294 /* Our naive response construction doesn't deal with IP 295 options, and probably shouldn't try. */ 296 if ((*pskb)->nh.iph->ihl<<2 != sizeof(struct iphdr)) 297 return NF_DROP; 298 299 /* WARNING: This code causes reentry within iptables. 300 This means that the iptables jump stack is now crap. We 301 must return an absolute verdict. --RR */ 302 switch (reject->with) { 303 case IPT_ICMP_NET_UNREACHABLE: 304 send_unreach(*pskb, ICMP_NET_UNREACH); 305 break; 306 case IPT_ICMP_HOST_UNREACHABLE: 307 send_unreach(*pskb, ICMP_HOST_UNREACH); 308 break; 309 case IPT_ICMP_PROT_UNREACHABLE: 310 send_unreach(*pskb, ICMP_PROT_UNREACH); 311 break; 312 case IPT_ICMP_PORT_UNREACHABLE: 313 send_unreach(*pskb, ICMP_PORT_UNREACH); 314 break; 315 case IPT_ICMP_NET_PROHIBITED: 316 send_unreach(*pskb, ICMP_NET_ANO); 317 break; 318 case IPT_ICMP_HOST_PROHIBITED: 319 send_unreach(*pskb, ICMP_HOST_ANO); 320 break; 321 case IPT_TCP_RESET: 322 send_reset(*pskb, hooknum == NF_IP_LOCAL_IN); 323 case IPT_ICMP_ECHOREPLY: 324 /* Doesn't happen. */ 325 break; 326 } 327 328 return NF_DROP; 329} 330 331static int check(const char *tablename, 332 const struct ipt_entry *e, 333 void *targinfo, 334 unsigned int targinfosize, 335 unsigned int hook_mask) 336{ 337 const struct ipt_reject_info *rejinfo = targinfo; 338 339 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) { 340 DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize); 341 return 0; 342 } 343 344 /* Only allow these for packet filtering. */ 345 if (strcmp(tablename, "filter") != 0) { 346 DEBUGP("REJECT: bad table `%s'.\n", tablename); 347 return 0; 348 } 349 if ((hook_mask & ~((1 << NF_IP_LOCAL_IN) 350 | (1 << NF_IP_FORWARD) 351 | (1 << NF_IP_LOCAL_OUT))) != 0) { 352 DEBUGP("REJECT: bad hook mask %X\n", hook_mask); 353 return 0; 354 } 355 356 if (rejinfo->with == IPT_ICMP_ECHOREPLY) { 357 printk("REJECT: ECHOREPLY no longer supported.\n"); 358 return 0; 359 } else if (rejinfo->with == IPT_TCP_RESET) { 360 /* Must specify that it's a TCP packet */ 361 if (e->ip.proto != IPPROTO_TCP 362 || (e->ip.invflags & IPT_INV_PROTO)) { 363 DEBUGP("REJECT: TCP_RESET illegal for non-tcp\n"); 364 return 0; 365 } 366 } 367 368 return 1; 369} 370 371static struct ipt_target ipt_reject_reg 372= { { NULL, NULL }, "REJECT", reject, check, NULL, THIS_MODULE }; 373 374static int __init init(void) 375{ 376 if (ipt_register_target(&ipt_reject_reg)) 377 return -EINVAL; 378 return 0; 379} 380 381static void __exit fini(void) 382{ 383 ipt_unregister_target(&ipt_reject_reg); 384} 385 386module_init(init); 387module_exit(fini); 388MODULE_LICENSE("GPL"); 389