Пример #1
0
void *process_request(void *sock_id){

  char *host;
  char *serv_port;
  void *buf = malloc(BUF_START_SIZE+1);
  size_t bufsize = BUF_START_SIZE;
  int new_s_client =  (int) (intptr_t) sock_id;
  int s_server, proxy_port;
  int length=0, i, recieved, recieved_s, sent;
  struct addrinfo hints, *servinfo, *p;

/*declare for getpeername*/
  struct sockaddr_in sin;
  socklen_t sockLen = sizeof(struct sockaddr);
  int src_port;
  char ipstr[INET6_ADDRSTRLEN];
  static char dstbuf[INET6_ADDRSTRLEN];
  char eth0_IP[INET6_ADDRSTRLEN];

/*declare for bind*/
  char SNAT[100];
  struct sockaddr_in serv_add;
  socklen_t serv_len = sizeof( struct sockaddr);
  bzero((char *)&serv_add, sizeof(serv_add));
  serv_add.sin_family = AF_INET;
  serv_add.sin_port = htons(0); 

/*declare for log*/
  int bytes_recv=0;
  int bytes_sent=0;

  pthread_detach(pthread_self());

  bzero(buf, bufsize);

  /* update number of threads currently operating */
  pthread_mutex_lock(&count_lock);
  num_threads++;
  printf("Increasing:%d\n",num_threads);
  pthread_mutex_unlock(&count_lock);

		/* recieve from client*/
		recieved = read(new_s_client, buf, bufsize);
		if(recieved < 0){
		printf("recieved error\n");
		free(host);
		free(buf);
		kill_thread();
		pthread_cancel(pthread_self());
		return NULL;
		}else if(recieved == 0){
		close(new_s_client);
		close(s_server);
		return NULL;
		}
		printf("recv from client:%s\n",buf);

	/*getpeername -- client IP*/
	getpeername(new_s_client, (struct sockaddr*)&sin, &sockLen);
    struct sockaddr_in *s = (struct sockaddr_in *)&sin;
    src_port = ntohs(s->sin_port);
    inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);


	/*Get the server ip*/
	struct sockaddr_in dstaddr;
	socklen_t len = sizeof(dstaddr);

	if (getsockopt(new_s_client, SOL_IP, SO_ORIGINAL_DST, (struct sockaddr *) &dstaddr, &len) == -1) {
		perror("getsockopt");
		close(new_s_client);
	}

	inet_ntop(dstaddr.sin_family, &dstaddr.sin_addr, dstbuf, sizeof(dstbuf));
	printf("original destination %s:%u\n", dstbuf, ntohs(dstaddr.sin_port));

	host = malloc(strlen(dstbuf));
	sprintf(host, "%s", dstbuf);

	serv_port = malloc(sizeof (ntohs(dstaddr.sin_port)));
	sprintf(serv_port, "%u", ntohs(dstaddr.sin_port));

	getInterfaceIP("eth0", eth0_IP);
/*
	printf("client address: %s\n", ipstr);
//	printf("proxy port of server side: %d\n", proxy_port);
	printf("port of client: %d\n", src_port);
	printf("serverside_ip: %s\n", eth0_IP);
	printf("dst port:%s\n",serv_port);
	//addto_iptables (proxy_port, ipstr, dstbuf, eth0_IP, src_port, serv_port);
*/
	/* send request to the specified host */
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

	if ( (getaddrinfo(host, serv_port, &hints, &servinfo)) != 0) 
	{
		send_err(new_s_client, HTTP_ERR_502);
		free(host);
		free(buf);
		kill_thread();
		pthread_cancel(pthread_self());
		return NULL;
	}

	for(p = servinfo; p != NULL; p = p->ai_next) 
	{
		if ((s_server = socket(p->ai_family, p->ai_socktype,
						p->ai_protocol)) < 0){
			kill_thread();
			pthread_cancel(pthread_self()); 
			return NULL;
		}

		if ( (bind(s_server, (struct sockaddr *)&serv_add, sizeof(serv_add))) < 0){
			perror("cannot bind to socket");
			exit(1);
		}

		/*getsockname -- source port*/
		getsockname(s_server, (struct sockaddr*)&serv_add, &serv_len);
		proxy_port = ntohs(serv_add.sin_port);

		sprintf(SNAT, "iptables -t nat -A POSTROUTING --protocol tcp -d %s -j SNAT --sport %d --to-source %s", dstbuf, proxy_port, ipstr);
		system(SNAT);

		if (connect(s_server, p->ai_addr, p->ai_addrlen) < 0) 
		{
			close(s_server);
			continue;
		}
		break;
	}
    freeaddrinfo(servinfo);


	if (p == NULL){
		send_err(new_s_client, HTTP_ERR_500);
		free(host);
		free(buf);
		kill_thread();
		pthread_cancel(pthread_self());
		return NULL;
	}

		/*Send req to server*/
		if( ( sent = write(s_server, buf, recieved)) == -1 ){
			printf("Send error\n");
			free(host);
			free(buf);
			kill_thread();
			pthread_cancel(pthread_self());
			return NULL;
		}
		//printf("sent:%d\n", sent);
		bytes_sent += recieved;
		bzero(buf, bufsize);

	pthread_mutex_lock(&cache_write_lock);
	for (i = 0; i < MAX_NUM_THREADS; i++)
		sem_wait(&cache_read_sem);

//echo
	bytes_recv = echo(s_server, new_s_client, buf, bufsize);
	//printf("bytes recieved:%d\n",bytes_recv);

	for (i = 0; i < MAX_NUM_THREADS; i++)
		sem_post(&cache_read_sem);
	pthread_mutex_unlock(&cache_write_lock);

/*logging*/
	logEvent("%s %d %s %s %d %d\n", ipstr, src_port, host, serv_port, bytes_sent, bytes_recv );

	sprintf(SNAT, "iptables -t nat -D POSTROUTING --protocol tcp -d %s -j SNAT --sport %d --to-source %s", dstbuf, proxy_port, ipstr);
	system(SNAT);

	pthread_mutex_lock(&count_lock);
	num_threads--;
	printf("Decreasing:%d\n",num_threads);
	pthread_mutex_unlock(&count_lock);

	free(host);
	pthread_cancel(pthread_self());
	return NULL;
}
Пример #2
0
int main(int argc, char * argv[]){

	int MULTITHREADED = TRUE;
	void (*ret)(int);
	int s_client;
	int new_s_client;
	struct sockaddr_in sin;
	socklen_t sockLen = sizeof(struct sockaddr);
	uint16_t portnum;

	/*DNAT system call*/
	char DNAT[100];
	char eth1_IP[INET6_ADDRSTRLEN];
	char ip[INET6_ADDRSTRLEN];

	pthread_t thread;	  
	pthread_attr_t thread_attr;

	pthread_attr_init(&thread_attr);
	pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);

	if(geteuid() != 0){
		printf("This program must be run as root\n");
		exit(1);
	}
 
	ret = signal(SIGPIPE, SIG_IGN);
	if (ret == SIG_ERR){
		perror(argv[0]);
		exit(1);
	}

	if (argc == 2)	  
		portnum = (uint16_t)atoi(argv[1]);
	else{
		fprintf(stderr, "usage: proxy [-t] <portnum>\n");
		exit(1);
	}
  
	bzero((char *)&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(portnum); 

	/*  open a socket and attempt to bind to the given port */
	if ( (s_client = socket(PF_INET, SOCK_STREAM, 0)) < 0){
		perror("error requesting socket");
		exit (1);
	}

	setsockopt(s_client, SOL_SOCKET, SO_REUSEADDR, NULL, 0);

	if ( (bind(s_client, (struct sockaddr *)&sin, sizeof(sin))) < 0){
		perror("cannot bind to socket");
		exit(1);
	}

/*DNAT - System call*/
	getInterfaceIP("eth1", eth1_IP);
	//printf("proxy ip:%s\nproxy port num:%d\n", eth1_IP, sin.sin_port);
	sprintf(DNAT, "iptables -t nat -A PREROUTING --protocol tcp -i eth1 -j DNAT --to %s:%d", eth1_IP, portnum);
	system(DNAT);

	listen(s_client, MAX_QUEUE);
  
	pthread_mutex_init(&count_lock, NULL);
	pthread_mutex_init(&cache_write_lock, NULL);
	sem_init(&cache_read_sem, PTHREAD_PROCESS_PRIVATE, MAX_NUM_THREADS);

	while (1){
	 if (num_threads < MAX_NUM_THREADS){

		 if ( (new_s_client = accept(s_client, (struct sockaddr *)&sin, &sockLen)) < 0)
			continue;
			inet_ntop(sin.sin_family, &sin.sin_addr, ip, sizeof(ip));
			printf("connection from %s:%u\n", ip, ntohs(sin.sin_port));

		/*Implement multi-thread*/
		 if (MULTITHREADED)
		 {
		     if (pthread_create(&thread, &thread_attr, process_request, (void *) (long) new_s_client) != 0)
		     {
			     send_err(new_s_client, HTTP_ERR_500);
			     close(new_s_client);
		     }
		 }else{
			 process_request((void *) (long) new_s_client);
		  }
	 }else{
		sleep(1);
	 }
  }
  return 1;
}
Пример #3
0
void dhcp_server( void ) {
	char			*iface_pref, *euid_pref, *dbhost_pref, *force_chroot;
	char			*dhcp_high_load_c;
	int			dhcp_high_load;
	dhcp_message		message;
	u_int32_t		server_ip;
	struct passwd		*pass_struct;
	int			retval = 0, cc = 0, sentreply;

	iface_pref = my_GetDHCPint();
	server_ip = getInterfaceIP( iface_pref );
	init_DHCP_Socket( server_ip );

//	euid_pref = GetConfigVar( "effective-userid" );
//	pass_struct = getpwnam( euid_pref );
//	if (pass_struct) {
//		seteuid( pass_struct->pw_uid );
//		setegid( pass_struct->pw_gid );
//	}

	dbhost_pref = GetConfigVar( "mysql-host" );
	force_chroot = GetConfigVar( "force-localhost-chroot" );
//	if (strcmp(dbhost_pref,"localhost") || !strcmp(force_chroot, "yes")) {
//		// We cannot chroot if connect to the DB via
//		// a unix socket vs tcp
//		chroot( CHROOT_PATH );
//	}

	dhcp_high_load_c = GetConfigVar( "dhcp-high-load" );
	if (*dhcp_high_load_c == ' ') { dhcp_high_load_c = "16"; }
	dhcp_high_load = strtoul( dhcp_high_load_c, NULL, 10 );
	if (dhcp_high_load <= 4) { dhcp_high_load = 4; }
	if (dhcp_high_load >= 128) { dhcp_high_load = 128; }
	my_Check_Load( dhcp_high_load );

	InitSQLconnection();

	my_syslog( MLOG_DHCP, "docsis_server DHCP version %s activated", VERSION);
	Clear_Remote_Commands();

	while (dhcpd_exit_flag) { /* loop until universe collapses */
		/* update the PID file */
		update_pid_file();

		/* Clear Message Struct */
		memset( &message, 0, sizeof( dhcp_message ) );

		retval = getPacket( &message );
		if (retval == -2) Check_Remote_Commands();
		if (retval < 0) {
			// ping the MySQL server
			my_SQL_Ping();
			continue;
		}
		message.server_ip = server_ip;

		if (Check_Canary) { fprintf(stderr,"canary A died %llu %llu %llu "
				" %llu %llu %llu  %llu %llu %llu\n",Canaries); continue; }

 		DecodeOptions( &message );
		if (message.in_opts.message_type == 0) {
			message.in_opts.message_type = DHCP_REQUEST;
		}

		if (Check_Canary) { fprintf(stderr,"canary B died %llu %llu %llu "
				" %llu %llu %llu  %llu %llu %llu\n",Canaries); continue; }

		sentreply = 0;
		switch( message.in_opts.message_type ) {
		case DHCP_DISCOVER:
			sentreply = send_Offer( &message );
			break;

		case DHCP_REQUEST:
			sentreply = send_ACK( &message );
			break;

		case DHCP_RELEASE:
			/* checkRelease( &message ); */
			break;
		case DHCP_INFORM:
			sentreply = send_ACK( &message );
			break;

		case DHCP_DECLINE:
			/* ignore */
			break;

		case DHCP_LEASE_QUERY:	/* wierd ubR thingy  0x0d */
			sentreply = leaseQuery( &message );
			break;

		default: {
			my_syslog(LOG_WARNING, "unsupported DHCP message (%02x) %s -- ignoring",
				message.in_opts.message_type, message.s_macaddr );
			}
		}

		if (Check_Canary) { fprintf(stderr,"canary C died %llu %llu %llu "
				" %llu %llu %llu  %llu %llu %llu\n",Canaries); continue; }

		if (sentreply) my_Check_Load( dhcp_high_load );
		Check_Remote_Commands();
	}

	my_syslog(LOG_INFO, "exit");
	Flush_ALL_SQL_Updates();
	closelog();
	exit(0);
}
Пример #4
0
/*
	bootAgentNotice is used to notice the PM service that the boot Agent starts up. Also,
	the hostname and IP address is deliver to the PM service.
*/
static int bootAgentNotice(int dbg)
{
	int sock;
	char bsip[30];
	char myIP[30];
	char hostname[100];
	char sendbuf[1024];
	char recvbuf[1024];
	int socklen=0;
	fd_set rfds;
	int ret = 0;
	int retry = 0;
	struct timeval tv;
	struct sockaddr_in sendAddr;
	struct sockaddr_in recvaddr;
	if(dbg == 1)
		sprintf(bsip, "127.0.0.1\0");
	else
		bsDiscovery(bsip);
	getInterfaceIP("eth1", myIP, sizeof(myIP));
	if(getHostname(hostname, sizeof(hostname))==-1)
		return -1;
	printf("Hostname-->%s\n",hostname);
	sock=createUdpClient();
	if(sock==-1)
		return -1;
	memset(&sendAddr,0,sizeof(sendAddr));
	sendAddr.sin_family=AF_INET;
	sendAddr.sin_port=htons(POALPORT);
	sendAddr.sin_addr.s_addr=inet_addr(bsip);
	sprintf(sendbuf, "%s,%s\0", hostname, myIP);
	while(1)
	{
		if(sendto(sock, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&sendAddr, sizeof(sendAddr)) ==-1)
		{
			goto errexit;
		}
		socklen=1024;
		memset(recvbuf, 0, sizeof(recvbuf));
		memset(&tv, 0, sizeof(tv));	
		FD_ZERO(&rfds);
		FD_SET(sock, &rfds);
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		ret = select(sock+1, &rfds, NULL, NULL, &tv);
		if(ret ==  -1)
		{
			printf("Select Error\n");
			goto errexit;
		}else if(ret)
		{
			if (recvfrom(sock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&recvaddr, &socklen) > 0)
			{
				printf("%s\n", recvbuf);
				if(!strncmp(recvbuf, "OK", 2))
					break;
			}
		}else
		{
			printf("No Ack retry\n");
			if(retry > 5)
				break;
			retry++;
		}
			
	}
	close(sock);
	return 1;
errexit:
	close(sock);
	return -1;

}
Пример #5
0
int getRemoteARP(struct pm_cfg cfg, unsigned int targetIP, const char *device, char *mac)
{
    unsigned int        localIP;
    char                errbuf[PCAP_ERRBUF_SIZE] = {0};
    ARPPACKET           arp;
    struct bpf_program  fp;
    struct pcap_pkthdr  *header;
    const u_char        *pkt_data;
    int                 sent        = 0;
    int                 found       = 1;
    char                filter[100] = {0};
    struct in_addr      addr;
    pcap_t              *pHandle = pcap_open_live(device, SNAP_LEN, 0, ARP_WAIT_TIME, errbuf);

    if (pHandle == NULL)
    {
        syslog(LOG_ERR, "unable to open capture device %s: %s", device, errbuf);
        return -1;
    }
    if (getInterfaceIP(device, &localIP) < 0)
    {
        syslog(LOG_ERR, "unable to get IP address for %s", device);
        pcap_close(pHandle);
        return -1;
    }
    //send arp request to an IP.
    memset(&arp, 0, sizeof(arp));
    memset(arp.ethhdr.h_dest, 0xFF, ETH_ALEN);
    arp.ethhdr.h_proto = htons(ETH_P_ARP);
    arp.arphdr.ar_hrd  = htons(ETH_P_802_3);
    arp.arphdr.ar_pro  = htons(ETH_P_IP);
    arp.arphdr.ar_hln  = ETH_ALEN;              // Hardware size: 6(0x06)
    arp.arphdr.ar_pln  = 4;                     // Protocol size; 4
    arp.arphdr.ar_op   = htons(ARPOP_REQUEST);  // Opcode: request (0x0001)
    memset(arp.arphdr.ar_tha, 0, ETH_ALEN);
    arp.arphdr.ar_tip = targetIP;
    memcpy(arp.ethhdr.h_source, cfg.src_mac, ETH_ALEN);
    memcpy(arp.arphdr.ar_sha, cfg.src_mac, ETH_ALEN);
    arp.arphdr.ar_sip = localIP;

    addr.s_addr = targetIP;
    sprintf(filter, "arp host %s", inet_ntoa(addr));
    pcap_compile(pHandle, &fp, filter, 0, 0);
    pcap_setfilter(pHandle, &fp);

    pcap_sendpacket(pHandle, (unsigned char *)&arp, sizeof(arp));

    while (1) {
        int res = pcap_next_ex(pHandle, &header, &pkt_data);
        if (res == 1)
        {
            if (*(unsigned short *)(pkt_data + 12) == htons(0x0806) &&
                header->len >= sizeof(ARPPACKET))
            {
                ARPPACKET* p = (ARPPACKET *)pkt_data;
                if (p->arphdr.ar_op == htons(ARPOP_REPLY) && p->arphdr.ar_sip == targetIP)
                {
                    memcpy(mac, (const char *)p->ethhdr.h_source, ETH_ALEN);
                    found = 0;
                    if (cfg.flags & PM_DEBUG)
                    {
                        syslog(LOG_INFO, "ARP reply on '%s'['%s'] filter '%s'",
                                 device,
                                 printMACStr(mac),
                                 filter);
                    }
                    break;
                }
            }
        }
        if (res == 0)
        {
            if (sent++ < 2)
            {
                pcap_sendpacket(pHandle, (unsigned char *)&arp, sizeof(arp));
            }
            else
            {
                break;
            }
        }
        if (res == -1)
        {
            syslog(LOG_ERR, "error reading packet: %s", pcap_geterr(pHandle));
            break;
        }
    }
    pcap_close(pHandle);

    return found;
}