]> git.saurik.com Git - apple/network_cmds.git/blame_incremental - natd.tproj/icmp.c
network_cmds-245.1.3.tar.gz
[apple/network_cmds.git] / natd.tproj / icmp.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * natd - Network Address Translation Daemon for FreeBSD.
25 *
26 * This software is provided free of charge, with no
27 * warranty of any kind, either expressed or implied.
28 * Use at your own risk.
29 *
30 * You may copy, modify and distribute this software (icmp.c) freely.
31 *
32 * Ari Suutari <suutari@iki.fi>
33 *
34 * Based upon:
35 * $FreeBSD: src/sbin/natd/icmp.c,v 1.6 1999/08/28 00:13:45 peter Exp $
36 */
37
38#include <stdlib.h>
39#include <stdio.h>
40#include <unistd.h>
41#include <string.h>
42#include <ctype.h>
43
44#include <sys/types.h>
45#include <sys/socket.h>
46#include <sys/time.h>
47#include <errno.h>
48#include <signal.h>
49
50#include <netdb.h>
51
52#include <netinet/in.h>
53#include <netinet/in_systm.h>
54#include <netinet/ip.h>
55#include <netinet/ip_icmp.h>
56
57#include <alias.h>
58
59#include "natd.h"
60
61int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu)
62{
63 char icmpBuf[IP_MAXPACKET];
64 struct ip* ip;
65 struct icmp* icmp;
66 int icmpLen;
67 int failBytes;
68 int failHdrLen;
69 struct sockaddr_in addr;
70 int wrote;
71 struct in_addr swap;
72/*
73 * Don't send error if packet is
74 * not the first fragment.
75 */
76 if (ntohs (failedDgram->ip_off) & ~(IP_MF | IP_DF))
77 return 0;
78/*
79 * Dont respond if failed datagram is ICMP.
80 */
81 if (failedDgram->ip_p == IPPROTO_ICMP)
82 return 0;
83/*
84 * Start building the message.
85 */
86 ip = (struct ip*) icmpBuf;
87 icmp = (struct icmp*) (icmpBuf + sizeof (struct ip));
88/*
89 * Complete ICMP part.
90 */
91 icmp->icmp_type = ICMP_UNREACH;
92 icmp->icmp_code = ICMP_UNREACH_NEEDFRAG;
93 icmp->icmp_cksum = 0;
94 icmp->icmp_void = 0;
95 icmp->icmp_nextmtu = htons (mtu);
96/*
97 * Copy header + 64 bits of original datagram.
98 */
99 failHdrLen = (failedDgram->ip_hl << 2);
100 failBytes = failedDgram->ip_len - failHdrLen;
101 if (failBytes > 8)
102 failBytes = 8;
103
104 failBytes += failHdrLen;
105 icmpLen = ICMP_MINLEN + failBytes;
106
107 memcpy (&icmp->icmp_ip, failedDgram, failBytes);
108/*
109 * Calculate checksum.
110 */
111 icmp->icmp_cksum = PacketAliasInternetChecksum ((u_short*) icmp,
112 icmpLen);
113/*
114 * Add IP header using old IP header as template.
115 */
116 memcpy (ip, failedDgram, sizeof (struct ip));
117
118 ip->ip_v = 4;
119 ip->ip_hl = 5;
120 ip->ip_len = htons (sizeof (struct ip) + icmpLen);
121 ip->ip_p = IPPROTO_ICMP;
122 ip->ip_tos = 0;
123
124 swap = ip->ip_dst;
125 ip->ip_dst = ip->ip_src;
126 ip->ip_src = swap;
127
128 PacketAliasIn ((char*) ip, IP_MAXPACKET);
129
130 addr.sin_family = AF_INET;
131 addr.sin_addr = ip->ip_dst;
132 addr.sin_port = 0;
133/*
134 * Put packet into processing queue.
135 */
136 wrote = sendto (sock,
137 icmp,
138 icmpLen,
139 0,
140 (struct sockaddr*) &addr,
141 sizeof addr);
142
143 if (wrote != icmpLen)
144 Warn ("Cannot send ICMP message.");
145
146 return 1;
147}
148
149