8 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
15 #include "msg_parser.h"
18 #include "udp_server.h"
21 #define MAX_VIA_LINE_SIZE 240
22 #define MAX_RECEIVED_SIZE 57
26 /* checks if ip is in host(name) and ?host(ip)=name?
27 * ip must be in network byte order!
28 * resolver = DO_DNS | DO_REV_DNS; if 0 no dns check is made
29 * return 0 if equal */
30 int check_address(unsigned long ip, char *name, int resolver)
35 /* maybe we are lucky and name it's an ip */
36 if (strcmp(name, inet_ntoa( *(struct in_addr *)&ip ))==0)
39 /* try all names ips */
40 he=gethostbyname(name);
41 for(i=0; he->h_addr_list[i];i++){
42 if (*(unsigned long*)he->h_addr_list[i]==ip)
46 if (resolver&DO_REV_DNS){
48 he=gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
49 if (strcmp(he->h_name, name)==0)
51 for (i=0; he->h_aliases[i];i++){
52 if (strcmp(he->h_aliases[i],name)==0)
61 int forward_request(char * orig, char* buf,
64 struct route_elem* re,
65 unsigned long source_ip)
67 unsigned int new_len, via_len, received_len;
68 char line_buf[MAX_VIA_LINE_SIZE];
69 char received_buf[MAX_RECEIVED_SIZE];
71 int offset, s_offset, size;
72 struct sockaddr_in to;
76 via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n",
78 /* check if received needs to be added */
79 if (check_address(source_ip, msg->via1.host, received_dns)!=0){
80 received_len=snprintf(received_buf, MAX_RECEIVED_SIZE,
82 inet_ntoa(*(struct in_addr *)&source_ip));
85 new_len=len+via_len+received_len;
86 new_buf=(char*)malloc(new_len+1);
88 DPrint("ERROR: forward_request: out of memory\n");
91 /* copy msg till first via */
93 size=msg->via1.hdr-buf;
94 memcpy(new_buf, orig, size);
98 memcpy(new_buf+offset, line_buf, via_len);
100 /* modify original via if neccesarry (received=...)*/
102 if (msg->via1.params){
103 size= msg->via1.params-msg->via1.hdr-1; /*compensate for ';' */
105 size= msg->via1.host-msg->via1.hdr+strlen(msg->via1.host);
106 if (msg->via1.port!=0){
107 size+=strlen(msg->via1.hdr+size+1)+1; /* +1 for ':'*/
110 memcpy(new_buf+offset, orig+s_offset,
114 memcpy(new_buf+offset, received_buf, received_len);
115 offset+=received_len;
117 /* copy the rest of the msg */
118 memcpy(new_buf+offset, orig+s_offset, len-s_offset);
122 printf("Sending:\n%s.\n", new_buf);
123 printf("orig. len=%d, new_len=%d, via_len=%d, received_len=%d\n",
124 len, new_len, via_len, received_len);
126 to.sin_family = AF_INET;
127 to.sin_port = (re->port)?htons(re->port):htons(SIP_PORT);
128 /* if error try next ip address if possible */
130 if (re->host.h_addr_list[re->current_addr_idx+1])
131 re->current_addr_idx++;
134 /* ? not 64bit clean?*/
135 to.sin_addr.s_addr=*((long*)re->host.h_addr_list[re->current_addr_idx]);
138 re->tx_bytes+=new_len;
139 if (udp_send(new_buf, new_len, &to, sizeof(to))==-1){
156 /* removes first via & sends msg to the second */
157 int forward_reply(char * orig, char* buf,
163 unsigned int new_len, via_len,r;
165 int offset, s_offset, size;
167 struct sockaddr_in to;
171 /*check if first via host = us */
173 for (r=0; r<addresses_no; r++)
174 if(strcmp(msg->via1.host, names[r])==0) break;
175 if (r==addresses_no){
176 DPrint("ERROR: forward_reply: host in first via != me : %s\n",
178 /* send error msg back? */
182 /* we must remove the first via */
183 via_len=msg->via1.size;
184 size=msg->via1.hdr-buf;
186 /* keep hdr =substract hdr size +1 (hdr':') and add
188 via_len-=strlen(msg->via1.hdr)+1;
189 size+=strlen(msg->via1.hdr)+1;
192 new_buf=(char*)malloc(new_len);
194 DPrint("ERROR: forward_reply: out of memory\n");
197 memcpy(new_buf, orig, size);
199 s_offset=size+via_len;
200 memcpy(new_buf+offset,orig+s_offset, len-s_offset);
202 printf("Sending: to %s:%d, \n%s.\n",
204 (unsigned short)msg->via2.port,
206 /* fork? gethostbyname will probably block... */
207 he=gethostbyname(msg->via2.host);
209 DPrint("ERROR:forward_reply:gethostbyname failure\n");
212 to.sin_family = AF_INET;
213 to.sin_port = (msg->via2.port)?htons(msg->via2.port):htons(SIP_PORT);
214 to.sin_addr.s_addr=*((long*)he->h_addr_list[0]);
216 if (udp_send(new_buf,new_len, &to, sizeof(to))==-1)
223 if (new_buf) free(new_buf);