]>
git.saurik.com Git - apple/network_cmds.git/blob - natd.tproj/icmp.c
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * natd - Network Address Translation Daemon for FreeBSD.
25 * This software is provided free of charge, with no
26 * warranty of any kind, either expressed or implied.
27 * Use at your own risk.
29 * You may copy, modify and distribute this software (icmp.c) freely.
31 * Ari Suutari <suutari@iki.fi>
34 * $FreeBSD: src/sbin/natd/icmp.c,v 1.6 1999/08/28 00:13:45 peter Exp $
43 #include <sys/types.h>
44 #include <sys/socket.h>
51 #include <netinet/in.h>
52 #include <netinet/in_systm.h>
53 #include <netinet/ip.h>
54 #include <netinet/ip_icmp.h>
60 int SendNeedFragIcmp (int sock
, struct ip
* failedDgram
, int mtu
)
62 char icmpBuf
[IP_MAXPACKET
];
68 struct sockaddr_in addr
;
72 * Don't send error if packet is
73 * not the first fragment.
75 if (ntohs (failedDgram
->ip_off
) & ~(IP_MF
| IP_DF
))
78 * Dont respond if failed datagram is ICMP.
80 if (failedDgram
->ip_p
== IPPROTO_ICMP
)
83 * Start building the message.
85 ip
= (struct ip
*) icmpBuf
;
86 icmp
= (struct icmp
*) (icmpBuf
+ sizeof (struct ip
));
90 icmp
->icmp_type
= ICMP_UNREACH
;
91 icmp
->icmp_code
= ICMP_UNREACH_NEEDFRAG
;
94 icmp
->icmp_nextmtu
= htons (mtu
);
96 * Copy header + 64 bits of original datagram.
98 failHdrLen
= (failedDgram
->ip_hl
<< 2);
99 failBytes
= failedDgram
->ip_len
- failHdrLen
;
103 failBytes
+= failHdrLen
;
104 icmpLen
= ICMP_MINLEN
+ failBytes
;
106 memcpy (&icmp
->icmp_ip
, failedDgram
, failBytes
);
108 * Calculate checksum.
110 icmp
->icmp_cksum
= PacketAliasInternetChecksum ((u_short
*) icmp
,
113 * Add IP header using old IP header as template.
115 memcpy (ip
, failedDgram
, sizeof (struct ip
));
119 ip
->ip_len
= htons (sizeof (struct ip
) + icmpLen
);
120 ip
->ip_p
= IPPROTO_ICMP
;
124 ip
->ip_dst
= ip
->ip_src
;
127 PacketAliasIn ((char*) ip
, IP_MAXPACKET
);
129 addr
.sin_family
= AF_INET
;
130 addr
.sin_addr
= ip
->ip_dst
;
133 * Put packet into processing queue.
135 wrote
= sendto (sock
,
139 (struct sockaddr
*) &addr
,
142 if (wrote
!= icmpLen
)
143 Warn ("Cannot send ICMP message.");