+#define DEFAULT_MAX_FORWARDS 70
+
+/* This is 302 sipredirect function coded by Martin Pycko (m78pl@yahoo.com) */
+static int sip_sipredirect(struct sip_pvt *p, char *dest)
+{
+ char *cdest;
+ char *extension, *host, *port;
+ char tmp[80];
+ if (!dest || ast_strlen_zero(dest)) {
+ ast_log(LOG_WARNING, "This application requires these arguments: SIPRedirect(extension[@host[:port]])\n");
+ return 0;
+ }
+ cdest = ast_strdupa(dest);
+ if (!cdest) {
+ ast_log(LOG_ERROR, "Problem allocating the memory\n");
+ return 0;
+ }
+ extension = strsep(&cdest, "@");
+ host = strsep(&cdest, ":");
+ port = strsep(&cdest, ":");
+ if (!extension) {
+ ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
+ return 0;
+ }
+
+ /* we'll issue the redirect message here */
+ if (!host) {
+ char *localtmp;
+ strncpy(tmp, get_header(&p->initreq, "To"), sizeof(tmp) - 1);
+ if (!strlen(tmp)) {
+ ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
+ return 0;
+ }
+ if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
+ char lhost[80], lport[80];
+ memset(lhost, 0, sizeof(lhost));
+ memset(lport, 0, sizeof(lport));
+ localtmp++;
+ /* This is okay becuase lhost and lport are as big as tmp */
+ sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
+ if (!strlen(lhost)) {
+ ast_log(LOG_ERROR, "Can't find the host address\n");
+ return 0;
+ }
+ host = ast_strdupa(lhost);
+ if (!host) {
+ ast_log(LOG_ERROR, "Problem allocating the memory\n");
+ return 0;
+ }
+ if (!ast_strlen_zero(lport)) {
+ port = ast_strdupa(lport);
+ if (!port) {
+ ast_log(LOG_ERROR, "Problem allocating the memory\n");
+ return 0;
+ }
+ }
+ }
+ }
+
+ /* make sure the forwarding won't be forever */
+ strncpy(tmp, get_header(&p->initreq, "Max-Forwards"), sizeof(tmp) - 1);
+ if (strlen(tmp) && atoi(tmp)) {
+ /* we found Max-Forwards in the original SIP request */
+ p->maxforwards = atoi(tmp) - 1;
+ } else {
+ /* just send our 302 Moved Temporarily */
+ p->maxforwards = DEFAULT_MAX_FORWARDS - 1;
+ }
+ if (p->maxforwards > -1) {
+ snprintf(p->our_contact, sizeof(p->our_contact), "redirect <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
+ transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1);
+ } else {
+ transmit_response(p, "483 Too Many Hops", &p->initreq);
+ }
+ /* this is all that we want to send to that SIP device */
+ ast_set_flag(p, SIP_ALREADYGONE);
+
+ /* hangup here */
+ return -1;
+}
+