- replaced get_ip_by_ifname by a simpler routine

(needs to be *BSD tested yet!)
- removed old hostname based config of in/outbound interfaces
- experimental feature: additional masquerading of UA registrered
  host parts of their SIP URL
This commit is contained in:
Thomas Ries
2003-03-09 20:49:50 +00:00
parent 458525e345
commit cdd05e2706
8 changed files with 162 additions and 225 deletions
+14 -4
View File
@@ -1,15 +1,25 @@
0.2.7
=====
- 9-Mar-2003: - replaced get_ip_by_ifname by a simple one (to be *BSD tested)
- removed old host-name based style for in/outbound interface
configuration. This is only not done via interface names
- experimental: The host part of UA registration entries
can be masqueraded (mask_host, masked_host config items)
Siemens SIP phones seem to need this 'feature'.
0.2.6
=====
- 28-Jan-2003: - New Feature: RTP proxy should be able to handle multiple
- 28-Jan-2003: - released 0.2.6
- New Feature: RTP proxy should be able to handle multiple
media stream in the same session (audio + video)
- 21-Jan-2003: - Bugfix: crash in compare_url (MSN Messenger issue)
- 19-Jan-2003: - use of libosip-0.9.3 not possible yet -
- 21-Jan-2003: - Bugfix: crash in compare_url (MSN Messenger issue)
- 19-Jan-2003: - use of libosip-0.9.3 not possible yet -
libosip fails in msg_setproxy_authenticate
-> Bug in libosip? to be investigated!
- give IP address in debug for 'received packet'
- 'WARNING:proxy.c:202 request from/to unregistered UA' now
includes sender and destination url
- 17-Jan-2003: - OpenBSD: do not link against gnugetopt (Luke Renn)
- 17-Jan-2003: - OpenBSD: do not link against gnugetopt (Luke Renn)
0.2.5a
======
-97
View File
@@ -29,100 +29,6 @@ TODOs, in random order:
- multiple inbound interfaces
- multiple (audio + video) RTP streams (rewriting and RTP proxying)
per SIP session
---BUFFER DUMP follows---
49 4e 56 49 54 45 20 73 69 70 3a 63 67 72 61 68 INVITE sip:cgrah
61 6d 40 74 77 6f 6c 69 70 73 2d 74 72 61 6e 73 am@twolips-trans
6c 61 74 69 6f 6e 73 2e 63 6f 2e 75 6b 20 53 49 lations.co.uk SI
50 2f 32 2e 30 0d 0a 56 69 61 3a 20 53 49 50 2f P/2.0..Via: SIP/
32 2e 30 2f 55 44 50 20 32 31 37 2e 33 35 2e 39 2.0/UDP 217.35.9
36 2e 31 31 38 3a 35 30 36 30 3b 62 72 61 6e 63 6.118:5060;branc
68 3d 36 32 38 30 37 33 32 64 65 63 66 66 35 38 h=6280732decff58
30 38 63 38 34 31 35 64 35 31 31 66 39 37 62 38 08c8415d511f97b8
36 63 2e 30 0d 0a 53 65 73 73 69 6f 6e 2d 45 78 6c.0..Session-Ex
70 69 72 65 73 3a 20 33 36 30 30 0d 0a 46 72 6f pires: 3600..Fro
6d 3a 20 22 6a 63 6f 72 72 79 22 20 3c 73 69 70 m: "jcorry" <sip
3a 6a 63 6f 72 72 79 40 32 31 37 2e 33 35 2e 39 :jcorry@217.35.9
36 2e 31 31 38 3e 3b 74 61 67 3d 64 37 64 37 37 6.118>;tag=d7d77
65 30 32 2d 61 39 36 61 2d 34 33 30 33 2d 61 37 e02-a96a-4303-a7
38 65 2d 38 63 62 62 38 33 30 65 37 65 62 66 0d 8e-8cbb830e7ebf.
0a 54 6f 3a 20 3c 73 69 70 3a 63 67 72 61 68 61 .To: <sip:cgraha
6d 40 74 77 6f 6c 69 70 73 2d 74 72 61 6e 73 6c m@twolips-transl
61 74 69 6f 6e 73 2e 63 6f 2e 75 6b 3e 0d 0a 43 ations.co.uk>..C
61 6c 6c 2d 49 44 3a 20 34 35 63 66 30 35 34 66 all-ID: 45cf054f
2d 61 36 61 63 2d 34 34 62 38 2d 61 39 66 32 2d -a6ac-44b8-a9f2-
66 38 63 30 65 39 64 64 64 63 33 37 40 31 39 32 f8c0e9dddc37@192
2e 31 36 38 2e 30 2e 33 31 0d 0a 43 53 65 71 3a .168.0.31..CSeq:
20 31 20 49 4e 56 49 54 45 0d 0a 43 6f 6e 74 61 1 INVITE..Conta
63 74 3a 20 3c 73 69 70 3a 34 54 6e 6d 76 66 59 ct: <sip:4TnmvfY
45 50 54 59 4a 4d 42 4e 49 69 5a 43 35 30 46 4e EPTYJMBNIiZC50FN
79 35 73 30 44 54 2b 37 6b 41 39 6e 63 58 2b 76 y5s0DT+7kA9ncX+v
44 4b 74 36 30 54 6b 59 33 37 67 79 67 68 57 6c DKt60TkY37gyghWl
4f 5a 5a 69 78 4e 36 6c 4a 40 32 31 37 2e 33 35 OZZixN6lJ@217.35
2e 39 36 2e 31 31 38 3e 0d 0a 55 73 65 72 2d 41 .96.118>..User-A
67 65 6e 74 3a 20 57 69 6e 64 6f 77 73 20 52 54 gent: Windows RT
43 2f 31 2e 30 0d 0a 43 6f 6e 74 65 6e 74 2d 54 C/1.0..Content-T
79 70 65 3a 20 61 70 70 6c 69 63 61 74 69 6f 6e ype: application
2f 73 64 70 0d 0a 43 6f 6e 74 65 6e 74 2d 4c 65 /sdp..Content-Le
6e 67 74 68 3a 20 35 34 33 0d 0a 0d 0a 76 3d 30 ngth: 543....v=0
0d 0a 6f 3d 6a 6f 68 6e 73 70 63 20 30 20 30 20 ..o=johnspc 0 0
49 4e 20 49 50 34 20 32 31 37 2e 33 35 2e 39 36 IN IP4 217.35.96
2e 31 31 38 0d 0a 73 3d 73 65 73 73 69 6f 6e 0d .118..s=session.
0a 63 3d 49 4e 20 49 50 34 20 32 31 37 2e 33 35 .c=IN IP4 217.35
2e 39 36 2e 31 31 38 0d 0a 62 3d 43 54 3a 31 30 .96.118..b=CT:10
30 30 0d 0a 74 3d 30 20 30 0d 0a 6d 3d 61 75 64 00..t=0 0..m=aud
69 6f 20 33 39 39 32 36 20 52 54 50 2f 41 56 50 io 39926 RTP/AVP
20 39 37 20 31 31 31 20 31 31 32 20 36 20 30 20 97 111 112 6 0
38 20 34 20 35 20 33 20 31 30 31 0d 0a 61 3d 73 8 4 5 3 101..a=s
65 6e 64 6f 6e 6c 79 0d 0a 61 3d 72 74 70 6d 61 endonly..a=rtpma
70 3a 39 37 20 72 65 64 2f 38 30 30 30 0d 0a 61 p:97 red/8000..a
3d 72 74 70 6d 61 70 3a 31 31 31 20 53 49 52 45 =rtpmap:111 SIRE
4e 2f 31 36 30 30 30 0d 0a 61 3d 66 6d 74 70 3a N/16000..a=fmtp:
31 31 31 20 62 69 74 72 61 74 65 3d 31 36 30 30 111 bitrate=1600
30 0d 0a 61 3d 72 74 70 6d 61 70 3a 31 31 32 20 0..a=rtpmap:112
47 37 32 32 31 2f 31 36 30 30 30 0d 0a 61 3d 66 G7221/16000..a=f
6d 74 70 3a 31 31 32 20 62 69 74 72 61 74 65 3d mtp:112 bitrate=
32 34 30 30 30 0d 0a 61 3d 72 74 70 6d 61 70 3a 24000..a=rtpmap:
36 20 44 56 49 34 2f 31 36 30 30 30 0d 0a 61 3d 6 DVI4/16000..a=
72 74 70 6d 61 70 3a 30 20 50 43 4d 55 2f 38 30 rtpmap:0 PCMU/80
30 30 0d 0a 61 3d 72 74 70 6d 61 70 3a 38 20 50 00..a=rtpmap:8 P
43 4d 41 2f 38 30 30 30 0d 0a 61 3d 72 74 70 6d CMA/8000..a=rtpm
61 70 3a 34 20 47 37 32 33 2f 38 30 30 30 0d 0a ap:4 G723/8000..
61 3d 72 74 70 6d 61 70 3a 35 20 44 56 49 34 2f a=rtpmap:5 DVI4/
38 30 30 30 0d 0a 61 3d 72 74 70 6d 61 70 3a 33 8000..a=rtpmap:3
20 47 53 4d 2f 38 30 30 30 0d 0a 61 3d 72 74 70 GSM/8000..a=rtp
6d 61 70 3a 31 30 31 20 74 65 6c 65 70 68 6f 6e map:101 telephon
65 2d 65 76 65 6e 74 2f 38 30 30 30 0d 0a 61 3d e-event/8000..a=
66 6d 74 70 3a 31 30 31 20 30 2d 31 36 0d 0a 6d fmtp:101 0-16..m
3d 76 69 64 65 6f 20 33 37 30 30 32 20 52 54 50 =video 37002 RTP
---end of BUFFER DUMP---
11:21:35 ERROR:siproxd.c:210 msg_parse() failed... this is not good
v=0
o=johnspc 0 0 IN IP4 217.35.96.118
s=session
c=IN IP4 217.35.96.118
b=CT:10
t=0 0
m=audio 39926 RTP/AVP 97 111 112 6 0 8 4 5 3 101
a=sendonly
a=rtpmap:97 red/8000
a=rtpmap:111 SIREN/16000
a=fmtp:111 bitrate=16000
a=rtpmap:112 G7221/16000
a=fmtp:112 bitrate=24000
a=rtpmap:6 DVI4/16000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:4 G723/8000
a=rtpmap:5 DVI4/8000
a=rtpmap:3 GSM/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
m=video 37002 RTP
- automatized CVS snapshot beamed to siproxd homepage (siproxd.sourceforge.net)
- general security issues
@@ -140,6 +46,3 @@ TODOs, in random order:
- via loop detection: send 482 error code
- support Record-Route header
- BUFFER DUMP FOLLOWS - insert DEBUG before, with more info about content
(from/to, len, etc)
+17 -11
View File
@@ -7,18 +7,8 @@
#
######################################################################
# The IP addresses of the INBOUND and OUTBOUND interface can
# be specified as hostnames or in dotted decimal form:
# The interafce names of INBOUND and OUTBOUND interface.
#
# host_inbound=foo.bar.org
#
# or as dotted decimal IP:
#
# this is the old style - specifying IP addresses:
#host_inbound = 10.0.0.1
#host_outbound = my.external-ip.address
#
# the new way, simply give the interface name:
if_inbound = eth0
if_outbound = ppp0
@@ -123,3 +113,19 @@ rtp_timeout = 60
#
debug_level = 0x00000000
######################################################################
# Mask feature (experimental)
#
# Some UAs will always use the host/ip they register to as
# host part in the registration record (which will be the inbound
# ip address / hostname of the proxy) and can not be told to register a
# different host (public IP address). This Mask feature allows to force
# such a UA to be masqueraded to a different host.
# -> Siemens SIP Phones seem to need this feature.
#
# mask_host=<inbound_ip/hostname>
# masked_host=<hostname_to_be_masqueraded_as>
#
# mask_host=<10.0.1.1> -- inbound IP address of proxy
# masked_host=<my.public.host> -- outbound hostname proxy
+14 -6
View File
@@ -74,6 +74,7 @@ int proxy_request (sip_t *request) {
sts=check_vialoop(request);
if (sts == STS_TRUE) {
DEBUGC(DBCLASS_PROXY,"via loop detected, ignoring request");
/* according to the SIP RFC we are supposed to return an 482 error */
return STS_FAILURE;
}
@@ -90,8 +91,8 @@ int proxy_request (sip_t *request) {
break;
}
/* outgoing request ('from' == 'masq') */
if (compare_url(request->from->url, urlmap[i].masq_url)==STS_SUCCESS) {
/* outgoing request ('from' == 'reg') */
if (compare_url(request->from->url, urlmap[i].reg_url)==STS_SUCCESS) {
type=REQTYP_OUTGOING;
DEBUGC(DBCLASS_PROXY,"outgoing request from %s@%s from inbound",
request->from->url->username,
@@ -292,6 +293,7 @@ int proxy_response (sip_t *response) {
sts=check_vialoop(response);
if (sts == STS_TRUE) {
DEBUGC(DBCLASS_PROXY,"via loop detected, ignoring response");
/* according to the SIP RFC we are supposed to return an 482 error */
return STS_FAILURE;
}
@@ -327,7 +329,7 @@ int proxy_response (sip_t *response) {
break;
}
/* outgoing response ('to' == 'masq') */
/* outgoing response ('to' == 'reg') */
if (compare_url(response->to->url, urlmap[i].masq_url)==STS_SUCCESS) {
type=RESTYP_OUTGOING;
DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound",
@@ -499,12 +501,16 @@ int proxy_add_myvia (sip_t *request, int interface) {
if (interface == 0) {
sts = get_ip_by_ifname(configuration.outbound_if, &addr);
if (sts == STS_FAILURE) {
sts = get_ip_by_host(configuration.outboundhost, &addr);
ERROR("can't find outbound interface %s - configuration error?",
configuration.outbound_if);
return STS_FAILURE;
}
} else {
sts = get_ip_by_ifname(configuration.inbound_if, &addr);
if (sts == STS_FAILURE) {
sts = get_ip_by_host(configuration.inboundhost, &addr);
ERROR("can't find inbound interface %s - configuration error?",
configuration.inbound_if);
return STS_FAILURE;
}
}
@@ -601,7 +607,9 @@ int proxy_rewrite_invitation_body(sip_t *mymsg){
sts = get_ip_by_host(sdp_c_addr_get(sdp,-1,0), &lcl_clnt_addr);
sts = get_ip_by_ifname(configuration.outbound_if, &outb_addr);
if (sts == STS_FAILURE) {
sts = get_ip_by_host(configuration.outboundhost, &outb_addr);
ERROR("can't find outbound interface %s - configuration error?",
configuration.inbound_if);
return STS_FAILURE;
}
for (media_stream_no=0;;media_stream_no++) {
+36 -3
View File
@@ -120,14 +120,12 @@ static int parse_config (FILE *configfile) {
struct cfgopts {
char *keyword;
enum type {TYP_INT4, TYP_STRING, TYP_FLOAT} type;
enum type {TYP_INT4, TYP_STRING, TYP_FLOAT, TYP_STRINGA} type;
void *dest;
} configoptions[] = {
{ "debug_level", TYP_INT4, &configuration.debuglevel },
{ "sip_listen_port", TYP_INT4, &configuration.sip_listen_port },
{ "daemonize", TYP_INT4, &configuration.daemonize },
{ "host_inbound", TYP_STRING, &configuration.inboundhost },
{ "host_outbound", TYP_STRING, &configuration.outboundhost },
{ "if_inbound", TYP_STRING, &configuration.inbound_if },
{ "if_outbound", TYP_STRING, &configuration.outbound_if },
{ "rtp_port_low", TYP_INT4, &configuration.rtp_port_low },
@@ -143,6 +141,8 @@ static int parse_config (FILE *configfile) {
{ "proxy_auth_realm", TYP_STRING, &configuration.proxy_auth_realm },
{ "proxy_auth_passwd", TYP_STRING, &configuration.proxy_auth_passwd },
{ "proxy_auth_pwfile", TYP_STRING, &configuration.proxy_auth_pwfile },
{ "mask_host", TYP_STRINGA, &configuration.mask_host },
{ "masked_host", TYP_STRINGA, &configuration.masked_host },
{0, 0, 0}
};
@@ -186,11 +186,18 @@ static int parse_config (FILE *configfile) {
num=0;
switch (configoptions[k].type) {
//
// Integer4
//
case TYP_INT4:
num=sscanf(ptr,"%i",(int*)configoptions[k].dest);
DEBUGC(DBCLASS_BABBLE,"INT4=%i",*(int*)configoptions[k].dest);
break;
//
// String
//
case TYP_STRING:
/* the %as within sscanf seems to be not too portable.
* it is supposed to allocate the memory
@@ -206,6 +213,32 @@ static int parse_config (FILE *configfile) {
*(char**)configoptions[k].dest);
break;
//
// String array
//
case TYP_STRINGA:
{
/* figure out the amount of space we need */
char **dst;
int used=((stringa_t*)(configoptions[k].dest))->used;
// do I hace space left?
if (used<=CFG_STRARR_SIZE){
num=strlen(ptr)+1; /* include terminating zero!*/
tmpptr=(char*)malloc(num);
dst=&((stringa_t*)(configoptions[k].dest))->
string[used];
memcpy(dst, &tmpptr, sizeof(tmpptr));
num=sscanf(ptr,"%s",tmpptr);
DEBUGC(DBCLASS_BABBLE,"STRINGA[%i]=%s", used, (char*) (
((stringa_t*)(configoptions[k].dest))->string[used]) );
((stringa_t*)(configoptions[k].dest))->used++;
} else {
ERROR("no more space left in config string array %s",
configoptions[k].keyword);
}
break;
}
default:
break;
}
+38 -3
View File
@@ -60,7 +60,7 @@ void register_init(void) {
* STS_NEED_AUTH : authentication needed
*/
int register_client(sip_t *my_msg) {
int i, j, sts;
int i, j, n, sts;
int expires;
time_t time_now;
url_t *url1_to, *url1_contact;
@@ -111,7 +111,7 @@ int register_client(sip_t *my_msg) {
/* Update registration. There are two possibilities:
* - already registered, the update the existing record
* - already registered, then update the existing record
* - not registered, then create a new record
*/
url1_to=my_msg->to->url;
@@ -156,7 +156,40 @@ int register_client(sip_t *my_msg) {
url_clone( ((contact_t*)(my_msg->contacts->node->element))->url,
&urlmap[i].true_url); /* Contact: field */
url_clone( my_msg->to->url,
&urlmap[i].masq_url); /* To: field */
&urlmap[i].reg_url); /* To: field */
/*
* try to figure out if we ought to do some masquerading
*/
url_clone( my_msg->to->url,
&urlmap[i].masq_url);
n=configuration.mask_host.used;
if (n != configuration.masked_host.used) {
ERROR("# of mask_host is not equal to # of masked_host in config!");
n=0;
}
DEBUG("%i entries in MASK config table", n);
for (j=0; j<n; j++) {
DEBUG("compare [%s] <-> [%s]",configuration.mask_host.string[j],
my_msg->to->url->host);
if (strcmp(configuration.mask_host.string[j],
my_msg->to->url->host)==0)
break;
}
if (j<n) {
/* we are masquerading this UA, replace the host part of the url */
DEBUGC(DBCLASS_REG,"masquerading UA %s@%s as %s@%s",
(url1_contact->username) ? url1_contact->username : "*NULL*",
(url1_contact->host) ? url1_contact->host : "*NULL*",
(url1_contact->username) ? url1_contact->username : "*NULL*",
configuration.masked_host.string[j]);
urlmap[i].masq_url->host=realloc(urlmap[i].masq_url->host,
strlen(configuration.masked_host.string[j])+1);
strcpy(urlmap[i].masq_url->host, configuration.masked_host.string[j]);
}
via_clone( ((via_t*)(my_msg->vias->node->element)),
&urlmap[i].via); /* via field */
}
@@ -189,9 +222,11 @@ void register_agemap(void) {
urlmap[i].active=0;
url_free(urlmap[i].true_url);
url_free(urlmap[i].masq_url);
url_free(urlmap[i].reg_url);
via_free(urlmap[i].via);
free(urlmap[i].true_url);
free(urlmap[i].masq_url);
free(urlmap[i].reg_url);
free(urlmap[i].via);
}
}
+22 -9
View File
@@ -79,19 +79,30 @@ int auth_include_authrq(sip_t *response); /*X*/
struct urlmap_s {
int active;
int expires;
url_t *true_url;
url_t *masq_url;
url_t *true_url; // true URL of UA (inbound URL)
url_t *masq_url; // masqueraded URL (outbound URL)
url_t *reg_url; // registered URL (masq URL as wished by UA)
via_t *via;
};
/*
* the difference between masq_url and reg_url is,
* the reg URL *always* holds the url registered by the UA.
* the masq_url may contain a different URL due to an additional
* masquerading feature (mask_host, masked_host config options)
*/
/*
* configuration option table
*/
#define CFG_STRARR_SIZE 128
typedef struct {
int used;
char *string[CFG_STRARR_SIZE];
} stringa_t;
struct siproxd_config {
int debuglevel;
char *inboundhost;
char *outboundhost;
char *inbound_if;
char *outbound_if;
int sip_listen_port;
@@ -108,6 +119,8 @@ struct siproxd_config {
char *proxy_auth_realm;
char *proxy_auth_passwd;
char *proxy_auth_pwfile;
stringa_t mask_host;
stringa_t masked_host;
};
@@ -116,8 +129,8 @@ struct siproxd_config {
*/
#define SIP_PORT 5060
#define URLMAP_SIZE 8 /* number of URL mapping table entries */
#define RTPPROXY_SIZE 8 /* number of rtp proxy entries */
#define URLMAP_SIZE 32 /* number of URL mapping table entries */
#define RTPPROXY_SIZE 64 /* number of rtp proxy entries */
#define BUFFER_SIZE 1024 /* input buffer for read from socket */
#define RTP_BUFFER_SIZE 512 /* max size of an RTP frame */
@@ -125,9 +138,9 @@ struct siproxd_config {
#define STATUSCODE_SIZE 5 /* size of string representation of status */
#define DNS_CACHE_SIZE 32 /* number of entries in internal DNS cache */
#define DNS_MAX_AGE 60 /* maximum age of an cache entry (sec) */
#define HOSTNAME_SIZE 32 /* max string length of a hostname */
#define USERNAME_SIZE 32 /* max string length of a username (auth) */
#define PASSWORD_SIZE 32 /* max string length of a password (auth) */
#define HOSTNAME_SIZE 64 /* max string length of a hostname */
#define USERNAME_SIZE 64 /* max string length of a username (auth) */
#define PASSWORD_SIZE 64 /* max string length of a password (auth) */
#define ACCESSCTL_SIP 1 /* for access control - SIP allowed */
+21 -92
View File
@@ -136,8 +136,6 @@ int check_vialoop (sip_t *my_msg) {
int is_via_local (via_t *via) {
int sts, found;
struct in_addr addr_via, addr_myself;
char *my_hostnames[]=
{ configuration.inboundhost, configuration.outboundhost, (char*)-1 };
char *my_interfaces[]=
{ configuration.inbound_if, configuration.outbound_if, (char*)-1 };
int port;
@@ -161,23 +159,8 @@ int is_via_local (via_t *via) {
if (ptr) {
DEBUGC(DBCLASS_BABBLE,"resolving IP of interface %s",ptr);
sts = get_ip_by_ifname(ptr, &addr_myself);
} else {
/*
* seems to be the old style config...
*/
ptr=my_hostnames[i];
if (ptr==NULL) {
ERROR("Could not find my local IP/interface configuration");
break;
}
DEBUGC(DBCLASS_BABBLE,"resolving IP of local name %s",ptr);
WARN("using hostnames for inbound/outbound interfaces is");
WARN("deprechiated - use interface names instead!");
sts = get_ip_by_host(ptr, &addr_myself);
}
/* check the extracted VIA against my own host addresses */
if (via->port) port=atoi(via->port);
else port=SIP_PORT;
@@ -409,89 +392,35 @@ void secure_enviroment (void) {
* get_ip_by_ifname:
* fetches own IP address by its interface name
*/
#define MAX_IF 32
int get_ip_by_ifname(char *ifname, struct in_addr *retaddr) {
struct in_addr addr;
int sock, err, i, found;
struct ifconf netconf;
char buffer[sizeof(struct ifreq)*MAX_IF];
struct ifreq *ifr;
int len, af;
struct ifreq ifr;
struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
int sockfd;
if (ifname == NULL) {
WARN("get_ip_by_ifname: got NULL ifname passed - please check config"
"file ('if_inbound' and 'if_outbound')");
return STS_FAILURE;
}
netconf.ifc_len=sizeof(struct ifreq)*MAX_IF;
netconf.ifc_buf=buffer;
bzero(&ifr, sizeof(ifr));
sock=socket(PF_INET, SOCK_DGRAM,0);
err=ioctl(sock,SIOCGIFCONF,&netconf);
if (err<0) ERROR("Error in ioctl: %s\n",strerror(errno));
close(sock);
if (log_get_pattern() && DBCLASS_BABBLE) {
for (i=0, ifr=(struct ifreq*)&buffer[i];
i<netconf.ifc_len;
ifr=(struct ifreq*)&buffer[i]) {
#if defined(_BSD)
len=((struct sockaddr *)&ifr->ifr_addr)->sa_len;
#else
/*
* Linux: fixed size. SA_LEN only works on 2.2.x kernels (RH6)
* seems to have disapeared on 2.4 (RH7)
* len=SA_LEN((struct sockaddr *)&ifr->ifr_addr);
*/
len=IFNAMSIZ;
#endif
af=((struct sockaddr *)&ifr->ifr_addr)->sa_family;
i+=len;
if(af != AF_INET) continue;
DEBUG("[i=%i] IF %s, l=%i af=%i -> IP:%s", i,
ifr->ifr_name, len, af, inet_ntoa(((struct sockaddr_in *)
(&ifr->ifr_addr))->sin_addr));
}
}
found=0;
memset(&addr, 0, sizeof(addr));
for (i=0, ifr=(struct ifreq*)&buffer[i];
i<netconf.ifc_len;
ifr=(struct ifreq*)&buffer[i]) {
#if defined(_BSD)
len=((struct sockaddr *)&ifr->ifr_addr)->sa_len;
#else
/*
* Linux: fixed size. SA_LEN only works on 2.2.x kernels (RH6)
* seems to have disapeared on 2.4 (RH7)
* len=SA_LEN((struct sockaddr *)&ifr->ifr_addr);
*/
len=IFNAMSIZ;
#endif
af=((struct sockaddr *)&ifr->ifr_addr)->sa_family;
i+=len;
if(af != AF_INET) continue;
if (strcmp(ifr->ifr_name, ifname)==0) {
memcpy(&addr, &((struct sockaddr_in *)
(&ifr->ifr_addr))->sin_addr,
sizeof(addr));
found=1;
break;
}
}
if (found==1) {
DEBUGC(DBCLASS_DNS, "get_ip_by_ifname: interface %s has IP: %s",
ifname, inet_ntoa(addr));
if (retaddr) memcpy(retaddr, &addr, sizeof(addr));
return STS_SUCCESS;
} else {
ERROR("get_ip_by_ifname: interface %s does not exist", ifname);
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
ERROR("Error in socket: %s\n",strerror(errno));
return STS_FAILURE;
}
strcpy(ifr.ifr_name, ifname);
sin->sin_family = AF_INET;
if(ioctl(sockfd, SIOCGIFADDR, &ifr) != 0) {
ERROR("Error in ioctl: %s\n",strerror(errno));
close(sockfd);
return STS_FAILURE;
}
DEBUGC(DBCLASS_DNS, "get_ip_by_ifname: interface %s has IP: %s",
ifname, inet_ntoa(sin->sin_addr));
if (retaddr) memcpy(retaddr, &sin->sin_addr, sizeof(sin->sin_addr));
return STS_SUCCESS;
}