[Vpn-help] Connectivity to Lucent VPN Gateway works, only pending issue *was* NAT :-)
Rolando J. Zappacosta
zappacor at gmail.com
Sun Apr 5 12:24:36 CDT 2009
Hi Matthew,
I managed to get your GREAT client to work with a Lucent VPN gateway
even under their way of workaround NAT.
As stated below what they do is to send *all* the traffic (control as
well as tunneled data) encapsulated in IP/UDP:501.
Do you think you could add above small piece of code to your program?
I think it could be added as another option within the
"Client-Firewalll Options-NAT Traversal" drop list and configuring
the port in "Client-Firewalll Options-NAT Traversal Port" (setting it
as 501 by default).
Well, the piece of code: compiling it and then running this makes the trick:
modprobe ip_queue
UDP501encap &
iptables -A OUTPUT -d <IPSEC GW address> -j QUEUE
iptables -A INPUT -s <IPSEC GW address> -j QUEUE
/sbin/rc-service iked start
/usr/bin/ikec
the code is:
RJZ-LNX UDP501 # cat UDP501encap.c
/*
* This code is GPL.
*/
/*
To compile:
gcc UDP501encap.c -o UDP501encap -lipq
*/
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/netfilter.h>
#include <libipq.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 2048
#define BOOL int
#define DstPort 501
#define DstPortHi DstPort >> 8
#define DstPortLo DstPort & 0x00FF
#define SrcPort 501
#define SrcPortHi SrcPort >> 8
#define SrcPortLo SrcPort & 0x00FF
typedef unsigned short u16;
typedef unsigned long u32;
u16 ip_sum_calc(u16 len_ip_header, unsigned char buff[])
{
u16 word16;
u32 sum=0;
u16 i;
// make 16 bit words out of every two adjacent 8 bit words in the packet
// and add them up
for (i=0;i<len_ip_header;i=i+2){
word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
sum = sum + (u32) word16;
}
// take only 16 bits out of the 32 bit sum and add up the carries
while (sum>>16)
sum = (sum & 0xFFFF)+(sum >> 16);
// one's complement the result
sum = ~sum;
return ((u16) sum);
}
static void die(struct ipq_handle *h)
{
ipq_perror("passer");
ipq_destroy_handle(h);
exit(1);
}
int main(int argc, char **argv)
{
int status;
unsigned char buf[BUFSIZE];
struct ipq_handle *h;
unsigned char *newPayload;
u16 srcaddr[4], dstaddr[4];
u16 newCS;
int ip_header_len;
u16 udp_len;
int i;
h = ipq_create_handle(0, PF_INET);
if (!h)
die(h);
status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
if (status < 0)
die(h);
do {
status = ipq_read(h, buf, BUFSIZE, 0);
if (status < 0)
die(h);
switch (ipq_message_type(buf))
{
case NLMSG_ERROR:
fprintf(stderr, "Received error
message %d\n", ipq_get_msgerr(buf));
break;
case IPQM_PACKET:
{
ipq_packet_msg_t *m = ipq_get_packet(buf);
//Enable this to debug the
incoming/outgoing packets:
//printf("0x%02x %s -> %s (%d)\n",
m->payload[9], m->indev_name, m->outdev_name, m->data_len);
if(m->outdev_name[0] == 0x0)
{
// INPUT
ip_header_len = (m->payload[0]
& 0xF) * 4;
u16 new_ip_len = m->data_len -
ip_header_len - 8;
newPayload =
malloc(new_ip_len);
memcpy(newPayload, m->payload
+ ip_header_len + 8, new_ip_len);
status = ipq_set_verdict(h,
m->packet_id, NF_ACCEPT, new_ip_len, newPayload);
free(newPayload);
}
else
{
u16 ip_len = (m->payload[2] <<
8 & 0xff00) + (m->payload[3] & 0xff);
ip_header_len = (m->payload[0]
& 0xF) * 4;
u16 new_ip_len = ip_len +
ip_header_len + 8;
newPayload =
malloc(new_ip_len);
// Copy prev packet
char *dst = newPayload;
char *org = m->payload;
// Copy IP header
memcpy(dst, org,
ip_header_len);
dst += ip_header_len;
// Update IP length field
newPayload[2] = new_ip_len >>
8;
newPayload[3] = new_ip_len &
0x00ff;
// Set IP protocol field to UDP
newPayload[9] = 0x11;
// Calculate and update IP cksum
newPayload[10] = newPayload[11] = 0x00;
newCS =
ip_sum_calc(ip_header_len, newPayload);
newPayload[10] = newCS >> 8;
newPayload[11] = newCS & 0x00FF;
// Create UDP header
dst[0] = SrcPortHi; // src port
dst[1] = SrcPortLo; // src port
dst[2] = DstPortHi; // dst port
dst[3] = DstPortLo; // dst port
u16 new_udp_len = new_ip_len -
ip_header_len;
dst[4] = new_udp_len >> 8; // total len
dst[5] = new_udp_len & 0x00ff;
// total len
dst[6] = 0x00; // Cksum
dst[7] = 0x00; // Cksum
dst += 8;
// Clone the rest of the packet
memcpy(dst, org, ip_len);
status = ipq_set_verdict(h,
m->packet_id, NF_ACCEPT, new_ip_len, newPayload);
free(newPayload);
}
if (status < 0)
die(h);
break;
}
default:
fprintf(stderr, "Unknown message type!\n");
break;
}
} while (1);
ipq_destroy_handle(h);
return 0;
}
RJZ-LNX UDP501 #
On 9/25/08, Rolando J. Zappacosta <zappacor at gmail.com> wrote:
>> The NAT Traversal option under the client tab enables ESP encapsulated
>> in UDP. The Shrew Soft client supports all Draft and RFC versions that I
>> am aware of. Try changing the port from 4500 to 501. You may also need
>> to tinker with the force/draft/rfc version option.
>
> I toyed with them but no luck. What happens is the gateway refuses the
> transforms proposals SS sends (it only accepts those stating
> "tunnel").
> What I should need is an option that doesn't change any in the
> negoatiation (neither try to detect NATT or propose any other
> "SA/proposal/transf payload/encap mode" than tunnel for Ph2) BUT to
> send ESP over UDP anyway.
>
More information about the vpn-help
mailing list