]>
git.saurik.com Git - apple/network_cmds.git/blob - natd.tproj/icmp.c
cc3ca98d005115d40d50cc0f06c6ec7570c7d1cf
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 * natd - Network Address Translation Daemon for FreeBSD.
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.
30 * You may copy, modify and distribute this software (icmp.c) freely.
32 * Ari Suutari <suutari@iki.fi>
35 * $FreeBSD: src/sbin/natd/icmp.c,v 1.6 1999/08/28 00:13:45 peter Exp $
44 #include <sys/types.h>
45 #include <sys/socket.h>
52 #include <netinet/in.h>
53 #include <netinet/in_systm.h>
54 #include <netinet/ip.h>
55 #include <netinet/ip_icmp.h>
61 int SendNeedFragIcmp (int sock
, struct ip
* failedDgram
, int mtu
)
63 char icmpBuf
[IP_MAXPACKET
];
69 struct sockaddr_in addr
;
73 * Don't send error if packet is
74 * not the first fragment.
76 if (ntohs (failedDgram
->ip_off
) & ~(IP_MF
| IP_DF
))
79 * Dont respond if failed datagram is ICMP.
81 if (failedDgram
->ip_p
== IPPROTO_ICMP
)
84 * Start building the message.
86 ip
= (struct ip
*) icmpBuf
;
87 icmp
= (struct icmp
*) (icmpBuf
+ sizeof (struct ip
));
91 icmp
->icmp_type
= ICMP_UNREACH
;
92 icmp
->icmp_code
= ICMP_UNREACH_NEEDFRAG
;
95 icmp
->icmp_nextmtu
= htons (mtu
);
97 * Copy header + 64 bits of original datagram.
99 failHdrLen
= (failedDgram
->ip_hl
<< 2);
100 failBytes
= failedDgram
->ip_len
- failHdrLen
;
104 failBytes
+= failHdrLen
;
105 icmpLen
= ICMP_MINLEN
+ failBytes
;
107 memcpy (&icmp
->icmp_ip
, failedDgram
, failBytes
);
109 * Calculate checksum.
111 icmp
->icmp_cksum
= PacketAliasInternetChecksum ((u_short
*) icmp
,
114 * Add IP header using old IP header as template.
116 memcpy (ip
, failedDgram
, sizeof (struct ip
));
120 ip
->ip_len
= htons (sizeof (struct ip
) + icmpLen
);
121 ip
->ip_p
= IPPROTO_ICMP
;
125 ip
->ip_dst
= ip
->ip_src
;
128 PacketAliasIn ((char*) ip
, IP_MAXPACKET
);
130 addr
.sin_family
= AF_INET
;
131 addr
.sin_addr
= ip
->ip_dst
;
134 * Put packet into processing queue.
136 wrote
= sendto (sock
,
140 (struct sockaddr
*) &addr
,
143 if (wrote
!= icmpLen
)
144 Warn ("Cannot send ICMP message.");