Hi Fatih,
you could spoof the natping's source-ip so it would apear to come from the
same host. I created a patch for that. It uses raw-sockets and works for me
on linux.
The patch is made against trunk. To use it, just set the udpping_from
parameter of module nathelper.
modparam("nathelper", "udpping_from" , "myhost:myport")
Feedback on this would be welcome.
Best regards,
Marcus
Fatih Cerit wrote:
> Hi all
>
> I am testing nat pinging. I have a natted UA and 2 opensers with
> diffrent ips. I decided to ping same nat from 2 opensers. I am going to
> have ability to increase ping interval from 15 seconds to 30
> seconds. But I don't have any idea that cross pinging works or not. Is
> there any one at there whom tested before or any suggestions??
>
> Thanks
> Fatih Cerit
--
Marcus Hunger - [EMAIL PROTECTED]
Telefon: +49 (0)211-63 55 55-61
Telefax: +49 (0)211-63 55 55-22
indigo networks GmbH - Gladbacher Str. 74 - 40219 Düsseldorf
HRB Düsseldorf 39841 - Geschäftsführer: Thilo Salmon, Tim Mois
Steuernummer: 133/5838/1589, Umsatzsteuer-ID: DE219349391
www.sipgate.de - www.sipgate.at - www.sipgate.co.uk
Index: modules/nathelper/nathelper.c
===================================================================
--- modules/nathelper/nathelper.c (revision 1712)
+++ modules/nathelper/nathelper.c (working copy)
@@ -154,6 +154,14 @@
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
+#ifndef __USE_BSD
+#define __USE_BSD
+#endif
+#include <netinet/ip.h>
+#ifndef __FAVOR_BSD
+#define __FAVOR_BSD
+#endif
+#include <netinet/udp.h>
#include <arpa/inet.h>
#include <sys/uio.h>
#include <sys/un.h>
@@ -250,6 +258,7 @@
static int cblen = 0;
static int natping_interval = 0;
struct socket_info* force_socket = 0;
+static int send_raw(const char *buf, int buf_len, union sockaddr_union *to);
static struct {
@@ -286,6 +295,7 @@
static pid_t mypid;
static unsigned int myseqn = 0;
static int rcv_avp_no = 42;
+static char *source_host = 0;
static str nortpproxy_str = str_init("a=nortpproxy:yes\r\n");
static int sipping_flag = -1;
@@ -350,6 +360,7 @@
{"sipping_from", STR_PARAM, &sipping_from.s },
{"sipping_method", STR_PARAM, &sipping_method.s },
{"sipping_bflag", INT_PARAM, &sipping_flag },
+ {"udpping_from", STR_PARAM, &source_host },
{0, 0, 0}
};
@@ -392,7 +403,67 @@
return 0;
}
+static unsigned int source_ip = 0;
+static unsigned int source_port = 0;
+static int raw_sock;
+static unsigned int host2addr(char *hostname)
+{
+ struct hostent *he;
+ int ip = 0;
+ char *dp = NULL;
+
+ dp = strchr(hostname, ':');
+ if (dp)
+ *dp = '\0';
+
+ he = resolvehost(hostname, 0);
+
+ if (!he || he->h_addrtype != AF_INET) {
+ LOG(L_ERR, "ERROR:host2addr: only ipv4 addresses allowed\n");
+ } else {
+ memcpy(&ip, he->h_addr_list[0], sizeof(ip));
+ }
+ if (dp)
+ *dp = ':';
+
+ return ip;
+}
+
+static unsigned short host2port(char *hostname)
+{
+ char *dp;
+ unsigned short ret = 5060; // default
+
+ dp = strchr(hostname, ':');
+
+ if (dp) {
+ dp++;
+ ret = atoi(dp);
+ }
+ return ret;
+}
+
+static int init_raw_socket()
+{
+ int on = 1;
+
+ raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+
+ if (raw_sock ==-1) {
+ LOG(L_ERR, "ERROR:init_raw_socket: cannot create raw socket\n");
+ return -1;
+ }
+
+ if(setsockopt(raw_sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) == -1) {
+ LOG(L_ERR, "ERROR:init_raw_socket: cannot set socket options\n");
+ return -1;
+ }
+ return raw_sock;
+}
+
+
+
static int
mod_init(void)
{
@@ -407,6 +478,17 @@
force_socket=grep_sock_info(&socket_str,0,0);
}
+ if (source_host && source_host[0]) {
+ source_ip = host2addr(source_host);
+ }
+
+ if (source_ip) {
+ source_port = host2port(source_host);
+ if (init_raw_socket() < 0) {
+ source_ip = 0;
+ }
+ }
+
if (nortpproxy_str.s==NULL || nortpproxy_str.s[0]==0) {
nortpproxy_str.len = 0;
nortpproxy_str.s = NULL;
@@ -2177,6 +2259,10 @@
if (udp_send(send_sock, opt.s, opt.len, &to)<0){
LOG(L_ERR, "ERROR:nathelper:nh_timer: sip udp_send failed\n");
}
+ } else if (source_ip) {
+ if (send_raw((char *) sbuf, sizeof(sbuf), &to) < 0) {
+ LOG(L_ERR, "ERROR:nathelper:nh_timer: send_raw failed\n");
+ }
} else {
if (udp_send(send_sock, (char *)sbuf, sizeof(sbuf), &to)<0 ) {
LOG(L_ERR, "ERROR:nathelper:nh_timer: udp udp_send failed\n");
@@ -2186,7 +2272,64 @@
pkg_free(buf);
}
+u_short checksum(unsigned char *buffer, int len)
+{
+ u_long sum = 0;
+ while (len > 1) {
+ sum += *buffer << 8;
+ buffer++;
+ sum += *buffer;
+ buffer++;
+ len -= 2;
+ }
+ if (len) {
+ sum += *buffer << 8;
+ }
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum = (sum >> 16) + (sum);
+
+ return (u_short) ~sum;
+}
+
+static int send_raw(const char *buf, int buf_len, union sockaddr_union *to)
+{
+ struct ip *ip;
+ struct udphdr *udp;
+ unsigned char packet[50];
+ int len = sizeof(struct ip) + sizeof(struct udphdr) + buf_len;
+
+ if (len > sizeof(packet)) {
+ LOG(L_ERR, "ERROR:send_raw: payload too big\n");
+ return -1;
+ }
+
+ ip = (struct ip*) packet;
+ udp = (struct udphdr *) (packet + sizeof(struct ip));
+ memcpy(packet + sizeof(struct ip) + sizeof(struct udphdr), buf, buf_len);
+
+ ip->ip_v = 4;
+ ip->ip_hl = sizeof(struct ip) / 4; // no options
+ ip->ip_tos = 0;
+ ip->ip_len = htons(len);
+ ip->ip_id = 23;
+ ip->ip_off = 0;
+ ip->ip_ttl = 69;
+ ip->ip_p = 17;
+ ip->ip_src.s_addr = source_ip;
+ ip->ip_dst.s_addr = to->sin.sin_addr.s_addr;
+
+ ip->ip_sum = checksum((unsigned char *) ip, sizeof(struct ip));
+
+ udp->uh_sport = htons(source_port);
+ udp->uh_dport = to->sin.sin_port;
+ udp->uh_ulen = htons((unsigned short) sizeof(struct udphdr) + buf_len);
+ udp->uh_sum = 0;
+
+ return sendto(raw_sock, packet, len, 0, (struct sockaddr *) to, sizeof(struct sockaddr_in));
+}
+
+
/*
* Create received SIP uri that will be either
* passed to registrar in an AVP or apended
_______________________________________________
Users mailing list
[email protected]
http://openser.org/cgi-bin/mailman/listinfo/users