Module: sip-router
Branch: andrei/raw_sock
Commit: ce63e6365ef3c9e9fa4914a90e71aaf599b02275
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ce63e63…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Thu Jul 8 17:28:46 2010 +0200
raw sockets: use BSD ip & udp structure versions
Use the BSD versions for the ip header structure (struct ip
instead of struct iphdr) and the udp header structure (struct
udphdr).
Since the BSD versions are used in most Unixes, this change would
make the code more portable.
---
raw_sock.c | 79 +++++++++++++++++++++++++++++++----------------------------
1 files changed, 41 insertions(+), 38 deletions(-)
diff --git a/raw_sock.c b/raw_sock.c
index 136f595..37ac6e5 100644
--- a/raw_sock.c
+++ b/raw_sock.c
@@ -29,7 +29,6 @@
*/
/*
* FIXME: IP_PKTINFO & IP_HDRINCL - linux specific
- * FIXME: linux specific iphdr and udphdr
*/
#ifdef USE_RAW_SOCKS
@@ -48,9 +47,13 @@
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
+#ifndef __USE_BSD
+#define __USE_BSD /* on linux use bsd version of iphdr (more portable) */
+#endif /* __USE_BSD */
#include <netinet/ip.h>
+#define __FAVOR_BSD /* on linux use bsd version of udphdr (more portable) */
#include <netinet/udp.h>
-#include <arpa/inet.h>
#include "raw_sock.h"
@@ -249,7 +252,7 @@ int raw_udp4_recv(int rsock, char** buf, int len, union
sockaddr_union* from,
char* end;
char* udph_start;
char* udp_payload;
- struct iphdr iph;
+ struct ip iph;
struct udphdr udph;
unsigned short udp_len;
@@ -257,21 +260,21 @@ int raw_udp4_recv(int rsock, char** buf, int len, union
sockaddr_union* from,
if (unlikely(n<0)) goto error;
end=*buf+n;
- if (unlikely(n<(sizeof(struct iphdr)+sizeof(struct udphdr)))) {
+ if (unlikely(n<(sizeof(struct ip)+sizeof(struct udphdr)))) {
n=-3;
goto error;
}
/* FIXME: if initial buffer is aligned, one could skip the memcpy
- and directly cast iphdr and udphdr pointer to the memory */
- memcpy(&iph, *buf, sizeof(struct iphdr));
- udph_start=*buf+iph.ihl*4;
+ and directly cast ip and udphdr pointer to the memory */
+ memcpy(&iph, *buf, sizeof(struct ip));
+ udph_start=*buf+iph.ip_hl*4;
udp_payload=udph_start+sizeof(struct udphdr);
if (unlikely(udp_payload>end)){
n=-3;
goto error;
}
memcpy(&udph, udph_start, sizeof(struct udphdr));
- udp_len=ntohs(udph.len);
+ udp_len=ntohs(udph.uh_ulen);
if (unlikely((udph_start+udp_len)!=end)){
if ((udph_start+udp_len)>end){
n=-3;
@@ -289,12 +292,12 @@ int raw_udp4_recv(int rsock, char** buf, int len, union
sockaddr_union* from,
/* fill ip from the packet (needed if no PKT_INFO is used) */
dst_ip.af=AF_INET;
dst_ip.len=4;
- dst_ip.u.addr32[0]=iph.daddr;
+ dst_ip.u.addr32[0]=iph.ip_dst.s_addr;
/* fill dst_port */
- dst_port=ntohs(udph.dest);
+ dst_port=ntohs(udph.uh_dport);
ip_addr2su(to, &dst_ip, dst_port);
/* fill src_port */
- src_port=ntohs(udph.source);
+ src_port=ntohs(udph.uh_sport);
su_setport(from, src_port);
if (likely(rf)) {
su2ip_addr(&dst_ip, to);
@@ -333,9 +336,9 @@ inline unsigned short udpv4_vhdr_sum( struct udphdr* uh,
/* pseudo header */
sum=(src->s_addr>>16)+(src->s_addr&0xffff)+
(dst->s_addr>>16)+(dst->s_addr&0xffff)+
- htons(IPPROTO_UDP)+(uh->len);
+ htons(IPPROTO_UDP)+(uh->uh_ulen);
/* udp header */
- sum+=(uh->dest)+(uh->source)+(uh->len) + 0 /*chksum*/;
+ sum+=(uh->uh_dport)+(uh->uh_sport)+(uh->uh_ulen) + 0 /*chksum*/;
/* fold it */
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
@@ -392,14 +395,14 @@ inline static int mk_udp_hdr(struct udphdr* u, struct sockaddr_in*
from,
struct sockaddr_in* to, unsigned char* buf, int len,
int do_chk)
{
- u->len=htons((unsigned short)len+sizeof(struct udphdr));
- u->source=from->sin_port;
- u->dest=to->sin_port;
+ u->uh_ulen=htons((unsigned short)len+sizeof(struct udphdr));
+ u->uh_sport=from->sin_port;
+ u->uh_dport=to->sin_port;
if (do_chk)
- u->check=htons(
+ u->uh_sum=htons(
udpv4_chksum(u, &from->sin_addr, &to->sin_addr, buf, len));
else
- u->check=0; /* no checksum */
+ u->uh_sum=0; /* no checksum */
return 0;
}
@@ -414,20 +417,20 @@ inline static int mk_udp_hdr(struct udphdr* u, struct sockaddr_in*
from,
* @param proto - protocol.
* @return 0 on success, < 0 on error.
*/
-inline static int mk_ip_hdr(struct iphdr* iph, struct in_addr* from,
+inline static int mk_ip_hdr(struct ip* iph, struct in_addr* from,
struct in_addr* to, int payload_len, unsigned char proto)
{
- iph->ihl = sizeof(struct iphdr)/4;
- iph->version = 4;
- iph->tos = tos;
- iph->tot_len = htons(payload_len);
- iph->id = 0;
- iph->frag_off = 0; /* first 3 bits = flags = 0, last 13 bits = offset */
- iph->ttl = 63; /* FIXME: use some configured value */
- iph->protocol = proto;
- iph->check = 0;
- iph->saddr = from->s_addr;
- iph->daddr = to->s_addr;
+ iph->ip_hl = sizeof(struct ip)/4;
+ iph->ip_v = 4;
+ iph->ip_tos = tos;
+ iph->ip_len = htons(payload_len);
+ iph->ip_id = 0;
+ iph->ip_off = 0; /* frag.: first 3 bits=flags=0, last 13 bits=offset */
+ iph->ip_ttl = 63; /* FIXME: use some configured value */
+ iph->ip_p = proto;
+ iph->ip_sum = 0;
+ iph->ip_src = *from;
+ iph->ip_dst = *to;
return 0;
}
@@ -509,7 +512,7 @@ int raw_iphdr_udp4_send(int rsock, char* buf, unsigned int len,
struct msghdr snd_msg;
struct iovec iov[2];
struct ip_udp_hdr {
- struct iphdr ip;
+ struct ip ip;
struct udphdr udp;
} hdr;
unsigned int totlen;
@@ -561,15 +564,15 @@ int raw_iphdr_udp4_send(int rsock, char* buf, unsigned int len,
/* if we are here mtu => sizeof(ip_h+udp_h) && payload > mtu
=> last_frag_offs >= sizeof(hdr.udp) */
last_frag_start = buf + last_frag_offs - sizeof(hdr.udp);
- hdr.ip.id = fastrand_max(65534) + 1; /* random id, should be != 0
+ hdr.ip.ip_id = fastrand_max(65534) + 1; /* random id, should be != 0
(if 0 the kernel will fill it) */
/* send the first fragment */
iov[1].iov_base=buf;
/* ip_frag_size >= sizeof(hdr.udp) because we are here only
if mtu >= sizeof(hdr.ip) + sizeof(hdr.udp) */
iov[1].iov_len=ip_frag_size - sizeof(hdr.udp);
- hdr.ip.tot_len = htons(ip_frag_size);
- hdr.ip.frag_off = htons(0x2000); /* set MF */
+ hdr.ip.ip_len = htons(ip_frag_size);
+ hdr.ip.ip_off = htons(0x2000); /* set MF */
ret=sendmsg(rsock, &snd_msg, 0);
if (unlikely(ret < 0))
goto end;
@@ -579,9 +582,9 @@ int raw_iphdr_udp4_send(int rsock, char* buf, unsigned int len,
/* fragments between the first and the last */
while(unlikely(iov[1].iov_base < last_frag_start)) {
iov[1].iov_len = ip_frag_size;
- hdr.ip.tot_len = htons(iov[1].iov_len);
+ hdr.ip.ip_len = htons(iov[1].iov_len);
/* set MF */
- hdr.ip.frag_off = htons( (unsigned short)
+ hdr.ip.ip_off = htons( (unsigned short)
(((char*)iov[1].iov_base - (char*)buf +
sizeof(hdr.udp)) / 8) | 0x2000);
ret=sendmsg(rsock, &snd_msg, 0);
@@ -591,9 +594,9 @@ int raw_iphdr_udp4_send(int rsock, char* buf, unsigned int len,
}
/* last fragment */
iov[1].iov_len = buf + len - (char*)iov[1].iov_base;
- hdr.ip.tot_len = htons(iov[1].iov_len);
+ hdr.ip.ip_len = htons(iov[1].iov_len);
/* don't set MF (last fragment) */
- hdr.ip.frag_off = htons( (unsigned short)
+ hdr.ip.ip_off = htons( (unsigned short)
(((char*)iov[1].iov_base - (char*)buf +
sizeof(hdr.udp)) / 8) );
ret=sendmsg(rsock, &snd_msg, 0);