add: add_via(buff, lport);
context: void shoot(char *buff, long address, int lport, int rport, int maxforw, int trace, int vbool, int fbool, int usrloc, int redirects){	struct sockaddr_in	addr, sockname;	struct timeval	tv;	struct pollfd sockerr;	int ssock, redirected, retryAfter, nretries;	int sock, i, len, ret, usrlocstep;	char	*contact, *crlf, *foo, *bar;	char	reply[1600];	fd_set	fd;	socklen_t slen;	regex_t* regexp;	regex_t* redexp;	redirected = 1;	nretries = 5;	retryAfter = 500;	usrlocstep = 0;	/* create a sending socket */	sock = (int)socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);	if (sock==-1) {		perror("no client socket");		exit(2);	}	/* create a listening socket */	ssock = (int)socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);	if (ssock==-1) {		perror("no server socket");		exit(2);	}	sockname.sin_family=AF_INET;	sockname.sin_addr.s_addr = htonl( INADDR_ANY );	sockname.sin_port = htons((short)lport);	if (bind( ssock, (struct sockaddr *) &sockname, sizeof(sockname) )==-1) {		perror("no bind");		exit(2);	}	/* for the via line we need our listening port number */	if ((vbool||usrloc) && lport==0){		memset(&sockname, 0, sizeof(sockname));		slen=sizeof(sockname);		getsockname(ssock, (struct sockaddr *)&sockname, &slen);		lport=ntohs(sockname.sin_port);	}	/* set a regular expression according to the modus */	regexp=(regex_t*)malloc(sizeof(regex_t));	if (trace)		regcomp(regexp, "^SIP/[0-9]\\.[0-9] 483 ", REG_EXTENDED|REG_NOSUB|REG_ICASE); 	else if (usrloc)		regcomp(regexp, "^SIP/[0-9]\\.[0-9] 200 ", REG_EXTENDED|REG_NOSUB|REG_ICASE); 	else		regcomp(regexp, "^SIP/[0-9]\\.[0-9] 1[0-9][0-9] ", REG_EXTENDED|REG_NOSUB|REG_ICASE); 	/* catching redirects */	redexp=(regex_t*)malloc(sizeof(regex_t));	regcomp(redexp, "^SIP/[0-9]\\.[0-9] 3[0-9][0-9] ", REG_EXTENDED|REG_NOSUB|REG_ICASE); 	/* determine our hostname */	get_fqdn();	if (usrloc){		nretries=3*(nameend-namebeg)+3;		create_msg(buff, REQ_REG, lport);		retryAfter = 5000;	}	if (trace){		if (maxforw)			nretries=maxforw;		else			nretries=255;		namebeg=1;		create_msg(buff, REQ_OPT, lport);	}	if(maxforw!=-1)		set_maxforw(buff, maxforw);	if(vbool)		add_via(buff, lport);	/* if we got a redirect this loop ensures sending to the 	   redirected server*/	while (redirected) {		redirected=0;		addr.sin_addr.s_addr = address;		addr.sin_port = htons((short)rport);		addr.sin_family = AF_INET;			/* we connect as per the RFC 2543 recommendations		modified from sendto/recvfrom */		ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));		if (ret==-1) {			perror("no connect");			exit(2);		}		for (i = 0; i < nretries; i++)		{			if (trace) {				set_maxforw(buff, i);			}			else if (usrloc && verbose) {				switch (usrlocstep) {					case 0:						printf("registering user %s%i... ", username, namebeg);						break;					case 1:						printf("sending message... ");						break;					case 2:						printf("sending message reply... ");						break;				}			}			else if (!trace && !usrloc){				printf("** request **\n%s\n", buff);			}			ret = send(sock, buff, strlen(buff), 0);			if (ret==-1) {				perror("send failure");				exit( 1 );			}					tv.tv_sec = retryAfter/1000;			tv.tv_usec = (retryAfter % 1000) * 1000;			FD_ZERO(&fd);			FD_SET(ssock, &fd); 			//ret = select(6, &fd, NULL, NULL, &tv);			ret = select(FD_SETSIZE, &fd, NULL, NULL, &tv);			if (ret == 0)			{				sockerr.fd=sock;				sockerr.events=POLLERR;				if ((poll(&sockerr, 1, 10))==1) {					if (sockerr.revents && POLLERR) {						printf("send failure:\n");						recv(sock, reply, strlen(reply), 0);						perror("");						exit(1);					}				}				printf("** timeout **\n");				retryAfter = retryAfter * 2;				if (retryAfter > 5000)					retryAfter = 5000;				/* we should have retrieved the error code and displayed				we are not doing that because there is a great variation				in the process of retrieveing error codes between				micro$oft and *nix world*/				continue;			} else if ( ret == -1 ) {				perror("select error");				exit(2);			} /* no timeout, no error ... something has happened :-) */			else if (FD_ISSET(ssock, &fd)) {			 	if (!trace && !usrloc)					puts ("\nmessage received");			} else {				puts("\nselect returned succesfuly, nothing received\n");				continue;			}			/* we are retrieving only the extend of a decent MSS = 1500 bytes */			len = sizeof(addr);			ret = recv(ssock, reply, 1500, 0);			if(ret > 0)			{				reply[ret] = 0;				if (redirects && regexec((regex_t*)redexp, reply, 0, 0, 0)==0) {					printf("** received redirect **\n");					/* we'll try to handle 301 and 302 here, other 3xx are to complex */					regcomp(redexp, "^SIP/[0-9]\\.[0-9] 30[1-2] ", REG_EXTENDED|REG_NOSUB|REG_ICASE);					if (regexec((regex_t*)redexp, reply, 0, 0, 0)==0) {						/* try to find the contact in the redirect */						if ((foo=strstr(reply, "Contact"))==NULL) {							printf("error: cannot find Contact in this redirect:\n%s\n", reply);							exit(2);						}						crlf=strchr(foo, '\n');						if ((contact=strchr(foo, '\r'))!=NULL && contact<crlf)							crlf=contact;						bar=malloc(crlf-foo+1);						strncpy(bar, foo, crlf-foo);						sprintf(bar+(crlf-foo), "\0");						if ((contact=strstr(bar, "sip"))==NULL) {							printf("error: cannot find sip in the Contact of this redirect:\n%s\n", reply);							exit(2);						}						if ((foo=strchr(contact, ';'))!=NULL)							*foo='\0';						if ((foo=strchr(contact, '>'))!=NULL)							*foo='\0';						if ((crlf=strchr(contact,':'))!=NULL){							crlf++;							/* extract the needed information*/							if ((foo=strchr(crlf,':'))!=NULL){								*foo='\0';								foo++;								rport = atoi(foo);								if (!rport) {									printf("error: cannot handle the port in the uri in Contact:\n%s\n", reply);									exit(2);								}							}							/* correct our request */							uri_replace(buff, contact);							if ((foo=strchr(contact,'@'))!=NULL){								foo++;								crlf=foo;							}							/* get the new destination IP*/							address = getaddress(crlf);							if (!address){								printf("error: cannot determine host address from Contact of redirect:\%s\n", reply);								exit(2);							}						}						else{							printf("error: missing : in Contact of this redirect:\n%s\n", reply);							exit(2);						}						free(bar);						memset(&addr, 0, sizeof(addr));						redirected=1;						i=nretries;					}					else {						printf("error: cannot handle this redirect:\n%s\n", reply);						exit(2);					}				}				else if (trace) {					/* in trace we only look for 483, anything else is 					   treated as the final reply*/					printf("%i: ", i+1);					if (regexec((regex_t*)regexp, reply, 0, 0, 0)==0) {						printf("* (483) \n");#ifdef DEBUG						printf("%s\n", reply);#endif						namebeg++;						create_msg(buff, REQ_OPT, lport);						continue;					}					else {						crlf=strchr(reply,'\n');						sprintf(crlf, "\0");						printf("%s\n", reply);						crlf++;						contact=strstr(crlf, "Contact");						if (contact){						crlf=strchr(contact,'\n');						sprintf(crlf, "\0");						printf("   %s\n", contact);						}						else {							printf("received reply without contact:\n%s\n"								, reply);						}						exit(0);					}				}				else if (usrloc) {					switch (usrlocstep) {						case 0:							/* at first we have sended a register a look at the 							   response now*/							if (regexec((regex_t*)regexp, reply, 0, 0, 0)==0) {								if (verbose)									printf ("  OK\n");#ifdef DEBUG								printf("\n%s\n", reply);#endif								strcpy(buff, message);								usrlocstep=1;							}							else {								if (verbose)									printf("received:\n%s\n", reply);								printf("error: didn't received '200 OK' on regsiter. aborting\n");								exit(1);							}							break;						case 1:							/* now we sended the message and look if its 							   forwarded to us*/							if (!strncmp(reply, MES_STR, MES_STR_LEN)) {								if (verbose) {									crlf=strstr(reply, "\r\n\r\n");									crlf=crlf+4;									printf("         received message\n  '%s'\n", crlf);								}#ifdef DEBUG								printf("\n%s\n", reply);#endif								cpy_vias(reply);								strcpy(buff, mes_reply);								usrlocstep=2;							}							else {								if (verbose)									printf("received:\n%s", reply);								printf("error: didn't received the 'MESSAGE' we sended. aborting\n");								exit(1);							}							break;						case 2:							/* finnaly we sended our reply on the message and 							   look if this is also forwarded to us*/							if (regexec((regex_t*)regexp, reply, 0, 0, 0)==0) {								if (verbose)									printf("   reply received\n\n");								else									printf("USRLOC for %s%i completed successful\n", username, namebeg);								if (namebeg==nameend) {									printf("All USRLOC tests completed successful.\n");									exit(0);								}								namebeg++;								create_msg(buff, REQ_REG, lport);								usrlocstep=0;							}							else {								if (verbose)									printf("received:\n%s\n", reply);								printf("error: didn't received the '200 OK' that we sended as the reply on the message\n");								exit(1);							}							break;					}				}				else {					/* in the normal send and reply case anything other then 					   1xx will be treated as final response*/					printf("** reply **\n%s\n", reply);					if (regexec((regex_t*)regexp, reply, 0, 0, 0)==0) {						puts(" provisional received; still waiting for a final response\n ");						continue;					} else {						puts(" final received; congratulations!\n ");						exit(0);					}				}					} 			else {				perror("recv error");				exit(2);			}		}	}	/* after all the retries, nothing has come back :-( */	puts("** I give up retransmission....");	exit(1);}