Exemplo n.º 1
0
int main(int argc, char *argv[])
#endif
{
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	uint8_t *state;
	uint8_t *server_id, *requested;
	uint32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	struct dhcpOfferedAddr static_lease;
	int max_sock;
	unsigned long num_ips;

	uint32_t static_lease_ip;

	memset(&server_config, 0, sizeof(struct server_config_t));
	read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);

	/* Start the log, sanitize fd's, and write a pid file */
	start_log_and_pid("udhcpd", server_config.pidfile);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;

	/* Sanity check */
	num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1;
	if (server_config.max_leases > num_ips) {
		LOG(LOG_ERR, "max_leases value (%lu) not sane, "
			"setting to %lu instead",
			server_config.max_leases, num_ips);
		server_config.max_leases = num_ips;
	}

	leases = xcalloc(server_config.max_leases, sizeof(struct dhcpOfferedAddr));
	read_leases(server_config.lease_file);

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		return 1;

#ifndef UDHCP_DEBUG
	background(server_config.pidfile); /* hold lock during fork. */
#endif

	/* Setup the signal pipe */
	udhcp_sp_setup();

	timeout_end = time(0) + server_config.auto_time;
	while(1) { /* loop until universe collapses */

		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %m");
				return 2;
			}

		max_sock = udhcp_sp_fd_set(&rfds, server_socket);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - time(0);
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			retval = select(max_sock + 1, &rfds, NULL, NULL,
					server_config.auto_time ? &tv : NULL);
		} else retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = time(0) + server_config.auto_time;
			continue;
		} else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}

		switch (udhcp_sp_read(&rfds)) {
		case SIGUSR1:
			LOG(LOG_INFO, "Received a SIGUSR1");
			write_leases();
			/* why not just reset the timeout, eh */
			timeout_end = time(0) + server_config.auto_time;
			continue;
		case SIGTERM:
			LOG(LOG_INFO, "Received a SIGTERM");
			return 0;
		case 0: break;		/* no signal */
		default: continue;	/* signal or error (probably EINTR) */
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %m, reopening socket");
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}

		/* Look for a static lease */
		static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr);

		if(static_lease_ip)
		{
			printf("Found static lease: %x\n", static_lease_ip);

			memcpy(&static_lease.chaddr, &packet.chaddr, 16);
			static_lease.yiaddr = static_lease_ip;
			static_lease.expires = 0;

			lease = &static_lease;

		}
		else
		{
		lease = find_lease_by_chaddr(packet.chaddr);
		}

		switch (state[0]) {
		case DHCPDISCOVER:
			DEBUG(LOG_INFO,"received DISCOVER");

			if (sendOffer(&packet) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;
 		case DHCPREQUEST:
			DEBUG(LOG_INFO, "received REQUEST");

			requested = get_option(&packet, DHCP_REQUESTED_IP);
			server_id = get_option(&packet, DHCP_SERVER_ID);

			if (requested) memcpy(&requested_align, requested, 4);
			if (server_id) memcpy(&server_id_align, server_id, 4);

			if (lease) {
				if (server_id) {
					/* SELECTING State */
					DEBUG(LOG_INFO, "server_id = %08x", ntohl(server_id_align));
					if (server_id_align == server_config.server && requested &&
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
				} else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else sendNAK(&packet);
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
						else {
							/* don't know what to do!!!! */
							sendNAK(&packet);
						}
					}
				}

			/* what to do if we have no record of the client */
			} else if (server_id) {
				/* SELECTING State */

			} else if (requested) {
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} else sendNAK(&packet);
				} else if (requested_align < server_config.start ||
					   requested_align > server_config.end) {
					sendNAK(&packet);
				} /* else remain silent */

			} else {
				 /* RENEWING or REBINDING State */
			}
			break;
		case DHCPDECLINE:
			DEBUG(LOG_INFO,"received DECLINE");
			if (lease) {
				memset(lease->chaddr, 0, 16);
				lease->expires = time(0) + server_config.decline_time;
			}
			break;
		case DHCPRELEASE:
			DEBUG(LOG_INFO,"received RELEASE");
			if (lease) lease->expires = time(0);
			break;
		case DHCPINFORM:
			DEBUG(LOG_INFO,"received INFORM");
			send_inform(&packet);
			break;
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
#endif
{	
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	unsigned char *state;
	unsigned char *server_id, *requested, *hostname;
	u_int32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	int pid_fd;
	int max_sock;
	int sig;

	/* DD-WRT (belanger) : ignore signals until we're ready */
	signal(SIGUSR1, SIG_IGN);
	signal(SIGUSR2, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGTERM, SIG_IGN);

	OPEN_LOG("udhcpd");
	LOG(LOG_INFO, "udhcp server (v%s) started", VERSION);

	memset(&server_config, 0, sizeof(struct server_config_t));

	if (argc < 2)
		read_config(DHCPD_CONF_FILE);
	else 
		read_config(argv[1]);

	pid_fd = pidfile_acquire(server_config.pidfile);
	pidfile_write_release(pid_fd);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;

	leases = malloc(sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	memset(leases, 0, sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	read_leases(server_config.lease_file);
	read_statics(server_config.statics_file);

	/* DD-WRT (belanger) : write leases now */
	write_leases();

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		exit_server(1);

#ifndef DEBUGGING
	pid_fd = pidfile_acquire(server_config.pidfile); /* hold lock during fork. */
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit_server(1);
	}
	pidfile_write_release(pid_fd);
#endif


	socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
	signal(SIGUSR1, signal_handler);
	signal(SIGUSR2, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);

	timeout_end = get_time(0) + server_config.auto_time;
	while(1) { /* loop until universe collapses */

		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %s", strerror(errno));
				exit_server(0);
			}			

		FD_ZERO(&rfds);
		FD_SET(server_socket, &rfds);
		FD_SET(signal_pipe[0], &rfds);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - get_time(0);
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			max_sock = server_socket > signal_pipe[0] ? server_socket : signal_pipe[0];
			retval = select(max_sock + 1, &rfds, NULL, NULL, 
					server_config.auto_time ? &tv : NULL);
		} 
		else 
			retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = get_time(0) + server_config.auto_time;
			continue;
		} 
		else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}
		
		if (FD_ISSET(signal_pipe[0], &rfds)) {
			if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
				continue; /* probably just EINTR */
			switch (sig) {
			case SIGUSR1:
				LOG(LOG_INFO, "Received a SIGUSR1");
				write_leases();
				/* why not just reset the timeout, eh */
				timeout_end = get_time(0) + server_config.auto_time;
				continue;
			case SIGUSR2:
				LOG(LOG_INFO, "Received a SIGUSR2");
				delete_leases();
				continue;
			case SIGHUP:
				LOG(LOG_INFO, "Received a SIGHUP");
				read_leases(server_config.lease_file);
				read_statics(server_config.statics_file);
				continue;
			case SIGTERM:
				LOG(LOG_INFO, "Received a SIGTERM");
				exit_server(0);
			}
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}

		hostname = get_option(&packet, DHCP_HOST_NAME);

		/* ADDME: look for a static lease */
		    
		/* If a hostname is supplied, and that hostname is a static lease, and that
		   static lease has an FF:FF:FF:FF:FF:FF MAC address, then use that entry. */
		if ( NULL == hostname ||
		     NULL == (lease = find_lease_by_hostname(hostname)) || 
		     (lease->expires != EXPIRES_NEVER) ||
		     0 != memcmp(lease->chaddr, MAC_BCAST_ADDR, strlen(MAC_BCAST_ADDR))) {
		  
		  /* Otherwise, look up the table using the supplied MAC address. */
		  lease = find_lease_by_chaddr(packet.chaddr);

		}

		switch (state[0]) {
		case DHCPDISCOVER:
			LOG(LOG_INFO,"received DISCOVER from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			
			if (sendOffer(&packet, lease) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;			
 		case DHCPREQUEST:
			requested = get_option(&packet, DHCP_REQUESTED_IP);
			server_id = get_option(&packet, DHCP_SERVER_ID);

			if (requested) memcpy(&requested_align, requested, 4);
			if (server_id) memcpy(&server_id_align, server_id, 4);
		
			if (requested) {
			  struct in_addr addr;
			  addr.s_addr = requested_align;
			  LOG(LOG_INFO, "received REQUEST for %s from %02x:%02x:%02x:%02x:%02x:%02x",
			      inet_ntoa(addr),
			      packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			      packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);
			}
			else {
			  LOG(LOG_INFO, "received REQUEST from %02x:%02x:%02x:%02x:%02x:%02x",
			      packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			      packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);
			}

			if (lease) { /*ADDME: or static lease */
				if (server_id) {
					/* SELECTING State */
					DEBUG(LOG_INFO, "server_id = %08x", ntohl(server_id_align));
					if (server_id_align == server_config.server && requested && 
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
					else
						sendNAK(&packet); //Sveasoft - shouldn't we let them know we don't like the request?
				} 
				else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else 
							sendNAK(&packet);
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
//						else if (!packet.ciaddr)
							/* Accept an invalid request in RENEWING state,
							   where the ciaddr should be set, but is not. */
							/* e.g. Linksys Print Server */
//							sendACK(&packet, lease->yiaddr); //note: let's not support broken stuff - Sveasoft 2005-01-19
						else {
							/* don't know what to do!!!! */
							sendNAK(&packet);
						}
					}						
				}
				if (lease->expires != EXPIRES_NEVER) {
					/* Don't change hostname of static leases */
					if (hostname) {
						bytes = hostname[-1];
						if (bytes >= (int) sizeof(lease->hostname))
							bytes = sizeof(lease->hostname) - 1;
						strncpy(lease->hostname, hostname, bytes);
							lease->hostname[bytes] = '\0';
					} else
						lease->hostname[0] = '\0';
				}
			
			/* what to do if we have no record of the client */
			} 
			else if (server_id) {
				/* SELECTING State */
				sendNAK(&packet);       // by honor

			} 
			else if (requested) {
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} 
					else 
						sendNAK(&packet);
				} 
				else if (requested_align < server_config.start || 
					 requested_align > server_config.end) {
					sendNAK(&packet);
				} 
				else {
					sendNAK(&packet);
				}

			} 
			else if (packet.ciaddr) {

				/* RENEWING or REBINDING State */
				sendNAK(&packet);
			}
			break;
		case DHCPDECLINE:
			LOG(LOG_INFO,"received DECLINE from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			if (lease && lease->expires != EXPIRES_NEVER) {
				memset(lease->chaddr, 0, 16);
				lease->expires = get_time(0) + server_config.decline_time;
			}			
			break;
		case DHCPRELEASE:
			LOG(LOG_INFO,"received RELEASE from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			if (lease && lease->expires != EXPIRES_NEVER) 
				lease->expires = get_time(0);
			break;
		case DHCPINFORM:
			LOG(LOG_INFO,"received INFORM from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			send_inform(&packet);
			break;	
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}
Exemplo n.º 3
0
int CXSPAsyncSocket::ListenSocket()
{
	return listen_socket(&m_socket);
}
Exemplo n.º 4
0
int main(int argc, char**argv)
{
  int msock; /* master socket */
  int ssock; /* slave socket */
  int portno; /* port to listen on */
  socklen_t clientlen; /* byte size of client's address */
  struct sockaddr_in serveraddr; /* server's addr */
  struct sockaddr_in clientaddr; /* client addr */
 
 
  char buf[400]; /* message buffer */
  char *hostaddrp; /* dotted decimal host addr string */
  int optval; /* flag value for setsockopt */
  int n; /* message byte size */

  if (argc != 2) {
    fprintf(stderr, "usage: %s <port>\n", argv[0]);
    exit(1);
  }
  portno = atoi(argv[1]);

  msock = create_socket(AF_207TCP, SOCK_207STREAM, IPPROTO_207TCP);
  if (msock < 0)
    perror("ERROR opening socket");

  bzero((char *) &serveraddr, sizeof(serveraddr));

  serveraddr.sin_family = AF_INET;
  serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
  serveraddr.sin_port = htons((unsigned short)portno);
  if (bind_socket(msock, (struct sockaddr_in *) &serveraddr,
       sizeof(serveraddr)) < 0)
    perror("ERROR on binding");
 
 
 
  while (1) {
     
      if (listen_socket(msock, 5) < 0) 
                perror("ERROR on listen");
 
  clientlen = sizeof(clientaddr);
  ssock = accept_connection(msock, (struct sockaddr_in *) &clientaddr, clientlen);
  if (ssock < 0)
    perror("ERROR on accept");
 
  pid_t childpid=fork();
 
  if (childpid  == 0)
  {
      //close(ssock);
      //int abc;
      //scanf("%d",&abc);
      char buffer[4000],converted[4000];
      int nr = recv_data(ssock,buffer,sizeof(buffer),0);
     
      int i;
      for(i=0;i<nr;i++)
      converted[i]=  toupper(buffer[i]);
      printf("\nConverted %s",converted);
      printf("\n\n");
      send_data(ssock,converted,sizeof(converted),0);
      //close_connection(ssock);
            nr = recv_data(ssock,buffer,sizeof(buffer),0);
     exit(0);      
  }
  }
 
 // int i;
 // for(i=0;i<3000;i++)
 // printf("\nData Recieved: %d\n%s",buffer[i]);

}
Exemplo n.º 5
0
int main(int argc, char *argv[])
#endif
{
	char *temp, *message;
	unsigned long t1 = 0, t2 = 0, xid = 0;
	unsigned long start = 0, lease;
	fd_set rfds;
	int fd, retval;
	struct timeval tv;
	int c, len;
	struct ifreq ifr;
	struct dhcpMessage packet;
	struct in_addr temp_addr;
	int pid_fd;

	static struct option options[] = {
		{"clientid",	required_argument,	0, 'c'},
		{"foreground",	no_argument,		0, 'f'},
		{"hostname",	required_argument,	0, 'H'},
		{"help",	no_argument,		0, 'h'},
		{"interface",	required_argument,	0, 'i'},
		{"now", 	no_argument,		0, 'n'},
		{"pidfile",	required_argument,	0, 'p'},
		{"quit",	no_argument,		0, 'q'},
		{"request",	required_argument,	0, 'r'},
		{"script",	required_argument,	0, 's'},
		{"version",	no_argument,		0, 'v'},
		{0, 0, 0, 0}
	};

	/* get options */
	while (1) {
		int option_index = 0;
// brcm
		c = getopt_long(argc, argv, "c:fH:hi:np:qr:s:d:v", options, &option_index);
		if (c == -1) break;
		
		switch (c) {
		case 'c':
			len = strlen(optarg) > 255 ? 255 : strlen(optarg);
			if (client_config.clientid) free(client_config.clientid);
			client_config.clientid = malloc(len + 2);
			client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
			client_config.clientid[OPT_LEN] = len;
			strncpy(client_config.clientid + 2, optarg, len);
			break;
		case 'f':
			client_config.foreground = 1;
			break;
		case 'H':
			len = strlen(optarg) > 255 ? 255 : strlen(optarg);
			if (client_config.hostname) free(client_config.hostname);
			client_config.hostname = malloc(len + 2);
			client_config.hostname[OPT_CODE] = DHCP_HOST_NAME;
			client_config.hostname[OPT_LEN] = len;
			strncpy(client_config.hostname + 2, optarg, len);
			break;
		case 'h':
			print_usage();
			return 0;
		case 'i':
			client_config.interface =  optarg;
// brcm
			strcpy(session_path, optarg);
			break;
		case 'n':
			client_config.abort_if_no_lease = 1;
			break;
		case 'p':
			client_config.pidfile = optarg;
			break;
		case 'q':
			client_config.quit_after_lease = 1;
			break;
		case 'r':
			requested_ip = inet_addr(optarg);
			break;
// brcm
		case 'd':
			strcpy(vendor_class_id, optarg);
			break;
		case 's':
			client_config.script = optarg;
			break;
		case 'v':
			printf("udhcpcd, version %s\n\n", VERSION);
			break;
		}
	}

	// brcm
        if (strlen(session_path) > 0) {
	    sprintf(status_path, "%s/%s/%s", _PATH_WAN_DIR, session_path, _PATH_MSG);
	    sprintf(pid_path, "%s/%s/%s", _PATH_WAN_DIR, session_path, _PATH_PID);
	}

	OPEN_LOG("udhcpc");
	LOG(LOG_INFO, "udhcp client (v%s) started", VERSION);

	pid_fd = pidfile_acquire(client_config.pidfile);
	pidfile_write_release(pid_fd);

	if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
		strcpy(ifr.ifr_name, client_config.interface);
		if (ioctl(fd, SIOCGIFINDEX, &ifr) == 0) {
			DEBUG(LOG_INFO, "adapter index %d", ifr.ifr_ifindex);
			client_config.ifindex = ifr.ifr_ifindex;
		} else {
			LOG(LOG_ERR, "SIOCGIFINDEX failed! %s", strerror(errno));
			exit_client(1);
		}
		if (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0) {
			memcpy(client_config.arp, ifr.ifr_hwaddr.sa_data, 6);
			DEBUG(LOG_INFO, "adapter hardware address %02x:%02x:%02x:%02x:%02x:%02x",
				client_config.arp[0], client_config.arp[1], client_config.arp[2], 
				client_config.arp[3], client_config.arp[4], client_config.arp[5]);
		} else {
			LOG(LOG_ERR, "SIOCGIFHWADDR failed! %s", strerror(errno));
			exit_client(1);
		}
	} else {
		LOG(LOG_ERR, "socket failed! %s", strerror(errno));
		exit_client(1);
	}
	close(fd);
	fd = -1;

	/* setup signal handlers */
	signal(SIGUSR1, renew_requested);
	signal(SIGUSR2, release_requested);
	signal(SIGTERM, terminate);
	
	state = INIT_SELECTING;
	// brcm
	// run_script(NULL, "deconfig");

	// brcm
	setStatus(0);

	for (;;) {
		if (fd > 0) {
			close(fd);
			fd = -1;
		}
		
		if (listen_mode == LISTEN_KERNEL) {
			if ((fd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface)) < 0) {
				LOG(LOG_ERR, "couldn't create server socket -- au revoir");
				exit_client(0);
			}			
		} else if (listen_mode == LISTEN_RAW) {
			if ((fd = raw_socket(client_config.ifindex)) < 0) {
				LOG(LOG_ERR, "couldn't create raw socket -- au revoir");
				exit_client(0);
			}			
		} else fd = -1;

		tv.tv_sec = timeout - time(0);
		tv.tv_usec = 0;
		FD_ZERO(&rfds);
		if (listen_mode) FD_SET(fd, &rfds);
		
	    if (tv.tv_sec > 0)
		   retval = select(fd + 1, &rfds, NULL, NULL, &tv);
		else 
           retval = 0; /* If we already timed out, fall through */
 
        //printf("state: %d, retval: %d \n", state, retval);
		if (retval == 0) {
			/* timeout dropped to zero */
			switch (state) {
			case INIT_SELECTING:
#if 0
				// brcm
				setStatus(0);
				if (packet_num < 3) {
					if (packet_num == 0)
						xid = random_xid();

					/* send discover packet */
					send_discover(xid, requested_ip); /* broadcast */
					
					timeout = time(0) + ((packet_num == 2) ? 10 : 2);
					packet_num++;
				} else {
					if (client_config.abort_if_no_lease) {
						LOG(LOG_INFO,
						    "No lease, failing.");
						exit_client(1);
				  	}
					/* wait to try again */
					packet_num = 0;
					timeout = time(0) + 60;
				}
				break;
#else
                                // brcm
                                setStatus(0);
                                   
                                if (packet_num < 4) 
                                {
                                   //if(dis_seq == 1)
                                   //{
                                   //   timeout = time(0) + 64;
                                   //}
                                   //else
                                   //{ 
                                      if(packet_num == 0)
                                      {
                                         xid = random_xid();
                                         timeout = time(0) + 4;
                                      }
                                      else if(packet_num == 1)
                                         timeout = time(0) + 8;
                                      else if(packet_num == 2)
                                         timeout = time(0) + 16;
                                      else if(packet_num == 3)
                                         timeout = time(0) + 32;
                                   //}
                                   //send_discover(xid, requested_ip); /* broadcast */
                                   packet_num++;
                                }
                                else
                                {
                                   if (client_config.abort_if_no_lease) 
                                   {
                                      LOG(LOG_INFO, "No lease, failing.");
                                      exit_client(1);
                                   }
                                   /* wait to try again */
                                   packet_num = 4;
                                   //dis_seq = 1;
                                   timeout = time(0) + 64;
                                }
                                /* send discover packet */
                                //printf("DHCP Discover state: %d, time: %d\n", packet_num, timeout);
                                send_discover(xid, requested_ip); /* broadcast */
                                break;
#endif
			case RENEW_REQUESTED:
			case REQUESTING:
#if 0
				if (packet_num < 3) {
					/* send request packet */
					if (state == RENEW_REQUESTED)
						send_renew(xid, server_addr, requested_ip); /* unicast */
					else send_selecting(xid, server_addr, requested_ip); /* broadcast */
					
					timeout = time(0) + ((packet_num == 2) ? 10 : 2);
					packet_num++;
				} else {
					/* timed out, go back to init state */
					state = INIT_SELECTING;
					timeout = time(0);
					packet_num = 0;
					listen_mode = LISTEN_RAW;
				}
				break;
#else
                                if(FirstPass == 1)
                                {
                                   if(packet_num < 1)
                                   {
                                      /* send request packet */
                                      if (state == RENEW_REQUESTED)
                                      {
                                         printf("RENEW_REQUESTED\n");
                                         send_renew(xid, server_addr, requested_ip); /* unicast */
                                      }
                                      else
                                      {
                                         printf("REQUESTING : %d\n", retval);
                                         send_selecting(xid, server_addr, requested_ip); /* broadcast */
                                      }
                                      timeout = time(0) + 64;
                                      packet_num++;
                                   }
                                   else
                                   {
                                      state = INIT_SELECTING;
                                      timeout = time(0);
                                      packet_num = 4;
                                      listen_mode = LISTEN_RAW;
                                   }
                                   break;
                                }

                                if (packet_num < 6) 
                                {
                                   if(packet_num == 0)
                                      timeout = time(0) + 4;
                                   else if(packet_num == 1)
                                      timeout = time(0) + 8;
                                   else if(packet_num == 2)
                                      timeout = time(0) + 16;
                                   else if(packet_num == 3)
                                      timeout = time(0) + 32;
                                   else  
                                      timeout = time(0) + 64;

                                   /* send request packet */
                                   if (state == RENEW_REQUESTED)
                                   {
                                      //printf("send renew 1\n");
                                      send_renew(xid, server_addr, requested_ip); /* unicast */
                                   }   
                                   else 
                                      send_selecting(xid, server_addr, requested_ip); /* broadcast */
                                   packet_num++;
                                } 
                                else 
                                {
                                   FirstPass = 1;
                                   /* timed out, go back to init state */
                                   state = INIT_SELECTING;
                                   timeout = time(0);
                                   packet_num = 4;
                                   listen_mode = LISTEN_RAW;
                                }
                                printf("RENEW_REQUESTED, REQUESTING ==> FirstPass: %d\n", FirstPass);
                                break;
#endif
			case BOUND:
				/* Lease is starting to run out, time to enter renewing state */
				state = RENEWING;
				listen_mode = LISTEN_KERNEL;
				DEBUG(LOG_INFO, "Entering renew state");
                                //printf("BOUND\n");
				/* fall right through */
			case RENEWING:
				/* Either set a new T1, or enter REBINDING state */
				if ((t2 - t1) <= (lease / 14400 + 1)) {
					/* timed out, enter rebinding state */
					state = REBINDING;
					timeout = time(0) + (t2 - t1);
					DEBUG(LOG_INFO, "Entering rebinding state");
                                        //printf("RENEWING\n");
				} else {
                                        //printf("send renew 2 , t1:%ld  t2:%ld  start:%ld\n", t1, t2, start);
					/* send a request packet */
					send_renew(xid, server_addr, requested_ip); /* unicast */
#if 0
					t1 = (t2 - t1) / 2 + t1;
					timeout = t1 + start;
#else
                                        t1 = t2;
                                        timeout = start + 4;
                                        packet_num = 0;
#endif
                                        //printf("timeout:%ld, t1:%ld\n", timeout, t1);
				}
				break;
			case REBINDING:
				/* Either set a new T2, or enter INIT state */
				if ((lease - t2) <= (lease / 14400 + 1)) {
					/* timed out, enter init state */
					state = INIT_SELECTING;
					LOG(LOG_INFO, "Lease lost, entering init state");
					run_script(NULL, "deconfig");
					timeout = time(0);
					packet_num = 0;
					listen_mode = LISTEN_RAW;
				} else {
					/* send a request packet */
					send_renew(xid, 0, requested_ip); /* broadcast */
#if 0
					t2 = (lease - t2) / 2 + t2;
					timeout = t2 + start;
#else
                                        if(packet_num < 5)
                                        {
                                           if(packet_num == 0)
                                              timeout = time(0) + 4;
                                           else if(packet_num == 1)
                                              timeout = time(0) + 8;
                                           else if(packet_num == 2)
                                              timeout = time(0) + 16;
                                           else if(packet_num == 3)
                                              timeout = time(0) + 32;
                                           else if(packet_num == 4)
                                              timeout = time(0) + 64;
 
                                           packet_num++ ;
                                        }
                                        else
                                        {
                                           /* timed out, go back to init state */
                                           state = INIT_SELECTING;
                                           timeout = time(0) + 0;
                                           packet_num = 0;
                                           listen_mode = LISTEN_RAW;
                                        }
#endif
				}
                                printf("REBINDING\n");
				break;
			case RELEASED:
				/* yah, I know, *you* say it would never happen */
				timeout = 0xffffffff;
                                //printf("RELEASED\n");
				break;
			}
		} else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd, &rfds)) {
			/* a packet is ready, read it */
			
			if (listen_mode == LISTEN_KERNEL) {
				if (get_packet(&packet, fd) < 0) continue;
			} else {
				if (get_raw_packet(&packet, fd) < 0) continue;
			} 
			
			if (packet.xid != xid) {
				DEBUG(LOG_INFO, "Ignoring XID %lx (our xid is %lx)",
					(unsigned long) packet.xid, xid);
				continue;
			}
			
			if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
				DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring");
				continue;
			}
			
			switch (state) {
			case INIT_SELECTING:
				/* Must be a DHCPOFFER to one of our xid's */
				if (*message == DHCPOFFER) {
					if ((temp = get_option(&packet, DHCP_SERVER_ID))) {
						memcpy(&server_addr, temp, 4);
						xid = packet.xid;
						requested_ip = packet.yiaddr;
						
						/* enter requesting state */
						state = REQUESTING;
						timeout = time(0);
						packet_num = 0;
					} else {
						DEBUG(LOG_ERR, "No server ID in message");
					}
				}
                                //dis_seq = 0;
                                //printf(" XXX INIT_SELECTING\n");
				break;
			case RENEW_REQUESTED:
			case REQUESTING:
			case RENEWING:
			case REBINDING:
				if (*message == DHCPACK) {
					if (!(temp = get_option(&packet, DHCP_LEASE_TIME))) {
						LOG(LOG_ERR, "No lease time with ACK, using 1 hour lease");
						lease = 60*60;
					} else {
						memcpy(&lease, temp, 4);
						lease = ntohl(lease);
					}
					FirstPass = 0;
                                        packet_num = 0;	
					/* enter bound state */
					t1 = lease / 2;
					
					/* little fixed point for n * .875 */
					t2 = (lease * 0x7) >> 3;
					temp_addr.s_addr = packet.yiaddr;
					LOG(LOG_INFO, "Lease of %s obtained, lease time %ld", 
						inet_ntoa(temp_addr), lease);
					start = time(0);
					timeout = t1 + start;
					requested_ip = packet.yiaddr;
					run_script(&packet,
						   ((state == RENEWING || state == REBINDING) ? "renew" : "bound"));
					state = BOUND;
					listen_mode = LISTEN_NONE;
					
					// brcm
					setStatus(1);
                    //printf("Receive Ack: timeout: %d Lease time: %ld, FirstPass: %d\n", timeout, lease, FirstPass);
					//background();
					
				} else if (*message == DHCPNAK) {
					/* return to init state */
					LOG(LOG_INFO, "Received DHCP NAK");
					if (state != REQUESTING)
						run_script(NULL, "deconfig");
					state = INIT_SELECTING;
					timeout = time(0);
					requested_ip = 0;
					packet_num = 0;
					listen_mode = LISTEN_RAW;

					// brcm
					setStatus(0);
				}
                                //printf("XXX RENEW_REQUESTED, REQUESTING, RENEWING, REBINDING\n");
				break;
			case BOUND:
			case RELEASED:
                                //printf("XXX BOUND, RELEASED\n");
				/* ignore all packets */
				break;
			}					
		} else if (retval == -1 && errno == EINTR) {
Exemplo n.º 6
0
int main (int argc, char **argv) {
   int h, i, fd1 = -1;
   char buf1[BUF_SIZE], buf2[BUF_SIZE];
   // buf1 what port reads from extern prog = tx
   // buf2 what port sends to extern prog   = rx 
   int buf1_avail = 0, buf1_written = 0;
   int buf2_avail = 0, buf2_written = 0;

// vars of my test prog
    char zeichen;
    char quitsignal = '#';

   if (argc != 2) {
       fprintf (stderr,
           "\n\t* * *  dl4mge 's PORTECHO. Little TCP test program  * * *\n"
	     "\t* * *  for tests with hf's mailbox function.        * * *\n"
	     "\n"
             "\tUsage: portecho  <port>, e.g. 'portecho 3333'.\n"
	     "\tQuit me with '#'. \n\n");
//		<forward-to-port> <forward-to-ip-address>\n");
       exit (1);
   }
       fprintf (stdout,
           "\n\t* * *  dl4mge 's PORTECHO. Little TCP test program  * * *\n"
	     "\t* * *  for tests with hf's mailbox function.        * * *\n"
	     "\n"
	     "\tTest me on another console by 'telnet localhost <port>'.\n"
	     "\tQuit me with '#'. \n\n");


   signal (SIGPIPE, SIG_IGN);
   h = listen_socket (atoi (argv[1]));
   if (h < 0) {
       fprintf (stderr, "error on opening port\n");
       exit (1);
    }
    for (;;) {
      for (;;) {
       int r, n = 0;
       fd_set rd, wr, er;
       FD_ZERO (&rd);
       FD_ZERO (&wr);
       FD_ZERO (&er);
       FD_SET (h, &rd);
       n = max (n, h);
       if (fd1 > 0 && buf1_avail < BUF_SIZE) {
       	   fprintf (stderr, "testport ready for read\n");
           FD_SET (fd1, &rd);
           n = max (n, fd1);
       }
       if (fd1 > 0
           && buf2_avail - buf2_written > 0) {
	   fprintf (stderr, "testport ready for write\n");
           FD_SET (fd1, &wr);
           n = max (n, fd1);
       }
       if (fd1 > 0) {
	   fprintf (stderr, "testport ready for err\n");
           FD_SET (fd1, &er);
           n = max (n, fd1);
       }
        r = select (n + 1, &rd, &wr, &er, NULL);
	if (r == -1 && errno == EINTR)
           continue;
	if (r < 0) {
           perror ("select()");
           exit (1);
	}
	if (FD_ISSET (h, &rd)) {
	    unsigned int l;
    	    struct sockaddr_in client_address;
    	    fprintf (stderr, "something tries to access port.\n");  
	    memset (&client_address, 0, l =sizeof (client_address));
    	    r = accept (h, (struct sockaddr *) &client_address, &l);
    	    fprintf (stderr, "I will try to accept peer port\n");  
    	    if (r < 0) {
    		perror ("accept() peer port");
    	    } else { 
    		fprintf (stderr, "I accepted peer port\n");  
        	fprintf (stderr, "r = %d\n",r);  	       
        	SHUT_FD1;
                buf1_avail = buf1_written = 0;
	        buf2_avail = buf2_written = 0;
    	        fd1 = r;
		sprintf(buf2, "%s", greeting);
		buf2_avail = strlen(greeting);
	    }
	}
//       /* NB: read oob data before normal reads 
        if (fd1 > 0)
    	    if (FD_ISSET (fd1, &er)) {
               char c;
               errno = 0;
               r = recv (fd1, &c, 1, MSG_OOB);
               if (r < 1) {
                   SHUT_FD1;
		} else
            	    fprintf (stderr, "error: %s, errno %d\n", &c, errno);  
		}
// READ
	if (fd1 > 0) {
           if (FD_ISSET (fd1, &rd)) {
	   	fprintf (stderr, "try read\n");       
		r =  read (fd1, buf1 + buf1_avail, BUF_SIZE - buf1_avail);
		if (r < 1) {
                   SHUT_FD1;
                } else {
		    buf1_avail += r;
            	    fprintf (stderr, "read %d chars\n", r);       
		    fprintf (stderr, "buf1: %s\n", buf1);       		
		}
	    
// PROCESS
		for (i = 0; i < buf1_avail && i < (BUF_SIZE - buf2_avail); i++) {
		    zeichen = buf1[buf1_written++];
			if (zeichen != quitsignal) {
			    buf2[buf2_avail++] = toupper(zeichen);			    
			}
			if (zeichen == quitsignal) {
		    	    fprintf (stderr, 
				"read: Signal to quit: %c !\n", zeichen);  
			    quit = 1;
		    	    sprintf(buf2, "%s", byebye);
			    buf2_avail = strlen(byebye);
			    //exit(0);
			}
		    }
		fprintf (stderr, "buf2: %s\n", buf2);       		
	    }
	}
// WRITE
        if (fd1 > 0) {
           if (FD_ISSET (fd1, &wr)) {
		fprintf (stderr, "write\n");       
                r = write (fd1, buf2 + buf2_written,
		  buf2_avail - buf2_written);
                if (r < 1) {
                   SHUT_FD1;
                } else {
                   buf2_written += r;
                }
	    }
	}
//       /* check if write data has caught read data 
        if (buf1_written == buf1_avail) {
    	    buf1_written = buf1_avail = 0;
	    memset(buf1, 0, sizeof(buf1));
	}
    	if (buf2_written == buf2_avail) {
	    buf2_written = buf2_avail = 0;
	    memset(buf2, 0, sizeof(buf2));
	    if (quit) {
		SHUT_FD1
		quit = 0;
		break;
	    }
	}
    
      }	
    }    
  return 0;
}
Exemplo n.º 7
0
int main(int argc, char *argv[])
#endif
{
	uint8_t *temp, *message;
	unsigned long t1 = 0, t2 = 0, xid = 0;
	unsigned long start = 0, lease;
	fd_set rfds;
	int retval;
	struct timeval tv;
	int c, len;
	struct dhcpMessage packet;
	struct in_addr temp_addr;
	long now;
	int max_fd;
	int sig;
	int no_clientid = 0;
	int fail_times = 0;		/* how many times that we fail to find a dhcp server */
	int server_unicast = 0;		


	static const struct option arg_options[] = {
		{"clientid",	required_argument,	0, 'c'},
		{"clientid-none", no_argument,		0, 'C'},
		{"foreground",	no_argument,		0, 'f'},
		{"background",	no_argument,		0, 'b'},
		{"hostname",	required_argument,	0, 'H'},
		{"hostname",    required_argument,      0, 'h'},
		{"interface",	required_argument,	0, 'i'},
		{"now", 	no_argument,		0, 'n'},
		{"pidfile",	required_argument,	0, 'p'},
		{"quit",	no_argument,		0, 'q'},
		{"request",	required_argument,	0, 'r'},
		{"script",	required_argument,	0, 's'},
		{"unicast",	no_argument,		0, 'u'},	/* unicast flag */
		{"version",	no_argument,		0, 'v'},
		{0, 0, 0, 0}
	};

	/* get options */
	while (1) {
		int option_index = 0;
		c = getopt_long(argc, argv, "c:CfbH:h:i:np:qr:s:uv", arg_options, &option_index);
		if (c == -1) break;

		switch (c) {
		case 'c':
			if (no_clientid) show_usage();
			len = strlen(optarg) > 255 ? 255 : strlen(optarg);
			if (client_config.clientid) free(client_config.clientid);
			client_config.clientid = xmalloc(len + 2);
			client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
			client_config.clientid[OPT_LEN] = len;
			client_config.clientid[OPT_DATA] = '\0';
			strncpy(client_config.clientid + OPT_DATA, optarg, len);
			break;
		case 'C':
			if (client_config.clientid) show_usage();
			no_clientid = 1;
			break;
		case 'f':
			client_config.foreground = 1;
			break;
		case 'b':
			client_config.background_if_no_lease = 1;
			break;
		case 'h':
		case 'H':
			len = strlen(optarg) > 255 ? 255 : strlen(optarg);
			if (client_config.hostname) free(client_config.hostname);
			client_config.hostname = xmalloc(len + 2);
			client_config.hostname[OPT_CODE] = DHCP_HOST_NAME;
			client_config.hostname[OPT_LEN] = len;
			strncpy(client_config.hostname + 2, optarg, len);
			break;
		case 'i':
			client_config.interface =  optarg;
			break;
		case 'n':
			client_config.abort_if_no_lease = 1;
			break;
		case 'p':
			client_config.pidfile = optarg;
			break;
		case 'q':
			client_config.quit_after_lease = 1;
			break;
		case 'r':
			requested_ip = inet_addr(optarg);
			break;
		case 's':
			client_config.script = optarg;
			break;
		case 'u':
			server_unicast = 1;
			break;
		case 'v':
			printf("udhcpcd, version %s\n\n", VERSION);
			return 0;
			break;
		default:
			show_usage();
		}
	}

	/* Start the log, sanitize fd's, and write a pid file */
	start_log_and_pid("udhcpc", client_config.pidfile);

	if (read_interface(client_config.interface, &client_config.ifindex,
			   NULL, client_config.arp) < 0)
		return 1;

	/* if not set, and not suppressed, setup the default client ID */
	if (!client_config.clientid && !no_clientid) {
		client_config.clientid = xmalloc(6 + 3);
		client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
		client_config.clientid[OPT_LEN] = 7;
		client_config.clientid[OPT_DATA] = 1;
		memcpy(client_config.clientid + 3, client_config.arp, 6);
	}

	/* changed by lsz 070621 */
	client_background();
	
	/* setup the signal pipe */
	udhcp_sp_setup();

	//if (dhcpc_shm_init() != 0)
	//	return -1;
	#include "msgq.h"
	dhcp_ipc_fork(DHCPC);

	state = INIT_SELECTING;
	run_script(NULL, "deconfig");
	change_mode(LISTEN_RAW);

	for (;;) {
		tv.tv_sec = timeout - uptime();
		tv.tv_usec = 0;

		if (listen_mode != LISTEN_NONE && fd < 0) {
			if (listen_mode == LISTEN_KERNEL)
				fd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface);
			else
				fd = raw_socket(client_config.ifindex);
			if (fd < 0) {
				LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m");
				return 0;
			}
		}
		
        /* 
         * select don't return when timeout value is larger than 1.5 hours
         * we just wait multiple times
         * added by tiger 090819, should fix later
         */
        struct timeval tp_timeout;
        #define TP_TIMEOUT_MAX  (30*60)
        
		if (tv.tv_sec > 0) 
		{
            do
            {
                max_fd = udhcp_sp_fd_set(&rfds, fd);
                
                tp_timeout.tv_sec = (tv.tv_sec > TP_TIMEOUT_MAX) ? TP_TIMEOUT_MAX : tv.tv_sec;
                tv.tv_sec -= tp_timeout.tv_sec;                                
                tp_timeout.tv_usec = 0;

                retval = select(max_fd + 1, &rfds, NULL, NULL, &tp_timeout);                
                
            } while (tv.tv_sec > 0 && retval == 0);
		}
		else
		{
			retval = 0; /* If we already timed out, fall through */
		}
        
		now = uptime();
		if (retval == 0) {
			/* timeout dropped to zero */
			switch (state) {
			case INIT_SELECTING:
               
#define     DISCOVER_RETRY_TIMES    5
#define     DISCOVER_INVERT_TIMES   3

				if (packet_num < DISCOVER_RETRY_TIMES) {
					if (packet_num == 0)
					{
						xid = random_xid();
                        /* use user config dhcp flags when first discover, added by tiger 20090821 */
                        if (server_unicast)
                        {
                            set_runtime_dhcp_flags(DHCP_FLAGS_UNICAST);
                        }
                        else
                        {
                            set_runtime_dhcp_flags(DHCP_FLAGS_BROADCAST);                            
                        }
					}

                    /* change runtime dhcp flags when exceed DISCOVER_INVERT_TIMES added by tiger 20090819 apply 11G and XP's option */
                    if (DISCOVER_INVERT_TIMES == packet_num)
                    {                        
                        invert_runtime_dhcp_flags();
                    }
                    
					/* send discover packet */
					//send_discover(xid, requested_ip, server_unicast); /* broadcast */
					/* modified by tiger 20090304, reply mode's setting way changed */
					send_discover(xid, requested_ip);
					msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPC Send DISCOVER with request ip %X and unicast flag %d", requested_ip, get_runtime_dhcp_flags());                    
                    
					timeout = now + ((packet_num == 2) ? 4 : 2);
					packet_num++;
				} else {
					run_script(NULL, "leasefail");
					msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPC DHCP Service unavailable, recv no OFFER");
					if (client_config.background_if_no_lease) {
						LOG(LOG_INFO, "No lease, forking to background.");
						client_background();
					} else if (client_config.abort_if_no_lease) {
						LOG(LOG_INFO, "No lease, failing.");
						return 1;
				  	}
					/* wait to try again */
					packet_num = 0;
					
					timeout = now + 10 + (fail_times ++) * 30;	
					/* 60->6000, we dont need to try again -- lsz, 080722 */
					/* 6000->30*fail_times -- lsz, 081008 */
				}
				break;
			case RENEW_REQUESTED:
			case REQUESTING:
				if (packet_num < 3) {
					/* send request packet */
					if (state == RENEW_REQUESTED)
					{
						send_renew(xid, server_addr, requested_ip); /* unicast */
					}
					else
					{
						send_selecting(xid, server_addr, requested_ip); /* broadcast */
					}

					msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPC Send REQUEST to server %x with request ip %x", server_addr, requested_ip);

					timeout = now + ((packet_num == 2) ? 10 : 2);
					packet_num++;
				} else {
					/* timed out, go back to init state */
					if (state == RENEW_REQUESTED) run_script(NULL, "deconfig");
					state = INIT_SELECTING;
					timeout = now;
					packet_num = 0;
					change_mode(LISTEN_RAW);
				}
				break;
			case BOUND:
				/* Lease is starting to run out, time to enter renewing state */
				state = RENEWING;
				change_mode(LISTEN_KERNEL);
				DEBUG(LOG_INFO, "Entering renew state");
				/* fall right through */
			case RENEWING:
				/* Either set a new T1, or enter REBINDING state */
				if ((t2 - t1) <= (lease / 14400 + 1)) {
					/* timed out, enter rebinding state */
					state = REBINDING;
					timeout = now + (t2 - t1);
					DEBUG(LOG_INFO, "Entering rebinding state");
				} else {
					/* send a request packet */				
					send_renew(xid, server_addr, requested_ip); /* unicast */

					msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPC Send REQUEST to server %x with request ip %x", server_addr, requested_ip);
              
					t1 = (t2 - t1) / 2 + t1;
					timeout = t1 + start;
				}
				break;
			case REBINDING:
				/* Either set a new T2, or enter INIT state */
				if ((lease - t2) <= (lease / 14400 + 1)) {
					/* timed out, enter init state */
					state = INIT_SELECTING;
					LOG(LOG_INFO, "Lease lost, entering init state");
					run_script(NULL, "deconfig");
					timeout = now;
					packet_num = 0;
					change_mode(LISTEN_RAW);
				} else {
					/* send a request packet */
					send_renew(xid, 0, requested_ip); /* broadcast */

					
					msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPC Broadcast REQUEST with request ip %x", requested_ip);
					t2 = (lease - t2) / 2 + t2;
					timeout = t2 + start;
				}
				break;
			case RELEASED:
				/* yah, I know, *you* say it would never happen */
				timeout = 0x7fffffff;
				break;
			}
		}
		else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd, &rfds)) {
			/* a packet is ready, read it */
			if (listen_mode == LISTEN_KERNEL)
				len = get_packet(&packet, fd);
			else len = get_raw_packet(&packet, fd);

			if (len == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %m, reopening socket");
				change_mode(listen_mode); /* just close and reopen */
			}
			if (len < 0) continue;

			if (packet.xid != xid) {
				DEBUG(LOG_INFO, "Ignoring XID %lx (our xid is %lx)",
					(unsigned long) packet.xid, xid);
				continue;
			}
			/* Ignore packets that aren't for us */
			if (memcmp(packet.chaddr, client_config.arp, 6)) {
				DEBUG(LOG_INFO, "packet does not have our chaddr -- ignoring");
				continue;
			}

			if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
				DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring");
				continue;
			}

			switch (state) {
			case INIT_SELECTING:
				/* Must be a DHCPOFFER to one of our xid's */
				if (*message == DHCPOFFER) {
					if ((temp = get_option(&packet, DHCP_SERVER_ID))) {
						memcpy(&server_addr, temp, 4);
						xid = packet.xid;
						requested_ip = packet.yiaddr;

						msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPC Recv OFFER from server %x with ip %x", server_addr, requested_ip);

						/* enter requesting state */
						state = REQUESTING;
						timeout = now;
						packet_num = 0;
					} else {
						DEBUG(LOG_ERR, "No server ID in message");
					}
				}
				break;
			case RENEW_REQUESTED:
			case REQUESTING:
			case RENEWING:
			case REBINDING:
				if (*message == DHCPACK) {
					if (!(temp = get_option(&packet, DHCP_LEASE_TIME))) {
						LOG(LOG_ERR, "No lease time with ACK, using 1 hour lease");
						lease = 60 * 60;
					} else {
						memcpy(&lease, temp, 4);
						lease = ntohl(lease);
					}

/* RFC 2131 3.1 paragraph 5:
 * "The client receives the DHCPACK message with configuration
 * parameters. The client SHOULD perform a final check on the
 * parameters (e.g., ARP for allocated network address), and notes
 * the duration of the lease specified in the DHCPACK message. At this
 * point, the client is configured. If the client detects that the
 * address is already in use (e.g., through the use of ARP),
 * the client MUST send a DHCPDECLINE message to the server and restarts
 * the configuration process..." 
 * added by tiger 20090827
 */                    
					if (!arpping(packet.yiaddr,
						    (uint32_t) 0,
						    packet.yiaddr,
						    client_config.arp,
						    client_config.interface)
					) {
					
						msglogd (LOG_INFO, LOGTYPE_DHCP, "DHCPC: offered address is in use "
							"(got ARP reply), Send decline");
						send_decline(xid, server_addr, packet.yiaddr);

						if (state != REQUESTING)
							run_script(NULL, "deconfig");
						change_mode(LISTEN_RAW);
						state = INIT_SELECTING;
						requested_ip = 0;
						timeout = now + 12;
						packet_num = 0;
						continue; /* back to main loop */
					}
                    
					/* enter bound state */
					t1 = lease / 2;

					/* little fixed point for n * .875 */
					t2 = (lease * 0x7) >> 3;
					temp_addr.s_addr = packet.yiaddr;
					LOG(LOG_INFO, "Lease of %s obtained, lease time %ld",
						inet_ntoa(temp_addr), lease);
					start = now;
					timeout = t1 + start;
					requested_ip = packet.yiaddr;

					if ((temp = get_option(&packet, DHCP_SERVER_ID))) 
						memcpy(&server_addr, temp, 4);
					msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPC Recv ACK from server %x with ip %x lease time %ld", 
						server_addr, requested_ip, lease);
					
					run_script(&packet,
						   ((state == RENEWING || state == REBINDING) ? "renew" : "bound"));

					fail_times = 0;		/* clear the retry counter */
					state = BOUND;
					change_mode(LISTEN_NONE);
					if (client_config.quit_after_lease)
						return 0;
					if (!client_config.foreground)
						client_background();

				} else if (*message == DHCPNAK) {
					/* return to init state */
					LOG(LOG_INFO, "Received DHCP NAK");

					if ((temp = get_option(&packet, DHCP_SERVER_ID))) 
						memcpy(&server_addr, temp, 4);
					msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPC Recv NAK from server %x with ip %x", server_addr, requested_ip);

					run_script(&packet, "nak");
					if (state != REQUESTING)
						run_script(NULL, "deconfig");
					state = INIT_SELECTING;
					timeout = now + 3;	/* change by lsz 080905, without this 3 seconds,
										 * the udhcpc will keep on trying and the release
										 * msg cant be recved by udhcpc, even if we are
										 * wan static ip now, the udhcpc is still sending 
										 * discover pkts. 
										 */
					requested_ip = 0;
					packet_num = 0;
					change_mode(LISTEN_RAW);
					//sleep(3); /* avoid excessive network traffic */
				}
				break;
			/* case BOUND, RELEASED: - ignore all packets */
			}
		} 
		else if (retval > 0 && (sig = udhcp_sp_read(&rfds))) {
Exemplo n.º 8
0
int main(int argc, char *argv[])
#endif
{	
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	unsigned char *state;
	unsigned char *server_id, *requested, *hostname;
	u_int32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	int pid_fd;
	int max_sock;
	int sig;
	
	OPEN_LOG("udhcpd");
	LOG(LOG_INFO, "udhcp server (v%s) started", VERSION);

	memset(&server_config, 0, sizeof(struct server_config_t));
	
	if (argc < 2)
		read_config(DHCPD_CONF_FILE);
	else read_config(argv[1]);

	pid_fd = pidfile_acquire(server_config.pidfile);
	pidfile_write_release(pid_fd);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;
	
	leases = malloc(sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	memset(leases, 0, sizeof(struct dhcpOfferedAddr) * server_config.max_leases);

	// Added by Joey to load static lease
	if (argc>=3)
	{
		load_leases(argv[2]);
	}

	read_leases(server_config.lease_file);

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		exit_server(1);

#ifndef DEBUGGING
	pid_fd = pidfile_acquire(server_config.pidfile); /* hold lock during fork. */
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit_server(1);
	}
	pidfile_write_release(pid_fd);
#endif

	/* ensure that stdin/stdout/stderr are never returned by pipe() */
	if (fcntl(STDIN_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_RDONLY);
	if (fcntl(STDOUT_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_WRONLY);
	if (fcntl(STDERR_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_WRONLY);

	/* setup signal handlers */
	pipe(signal_pipe);
	signal(SIGUSR1, signal_handler);
	signal(SIGTERM, signal_handler);

	timeout_end = uptime() + server_config.auto_time;
	while(1) { /* loop until universe collapses */

		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %s", strerror(errno));
				exit_server(0);
			}			

		FD_ZERO(&rfds);
		FD_SET(server_socket, &rfds);
		FD_SET(signal_pipe[0], &rfds);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - uptime();
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			max_sock = server_socket > signal_pipe[0] ? server_socket : signal_pipe[0];
			retval = select(max_sock + 1, &rfds, NULL, NULL, 
					server_config.auto_time ? &tv : NULL);
		} else retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = uptime() + server_config.auto_time;
			continue;
		} else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}
		
		if (FD_ISSET(signal_pipe[0], &rfds)) {
			if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
				continue; /* probably just EINTR */
			switch (sig) {
			case SIGUSR1:
				LOG(LOG_INFO, "Received a SIGUSR1");
				write_leases();
				/* why not just reset the timeout, eh */
				timeout_end = uptime() + server_config.auto_time;
				continue;
			case SIGTERM:
				LOG(LOG_INFO, "Received a SIGTERM");
				exit_server(0);
			}
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}
		
		server_id = get_option(&packet, DHCP_SERVER_ID);
		if (server_id) {
			memcpy(&server_id_align, server_id, 4);
			if (server_id_align != server_config.server) {
				/* client talks to somebody else */
				DEBUG(LOG_INFO,"server ID %08x doesn't match, ignoring", ntohl(server_id_align));
				continue;
			}
		}

		/* ADDME: look for a static lease */
		lease = find_lease_by_chaddr(packet.chaddr);
		switch (state[0]) {
		case DHCPDISCOVER:
			DEBUG(LOG_INFO,"received DISCOVER");
			
			if (sendOffer(&packet) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;			
 		case DHCPREQUEST:
			DEBUG(LOG_INFO, "received REQUEST");

			requested = get_option(&packet, DHCP_REQUESTED_IP);
			hostname = get_option(&packet, DHCP_HOST_NAME);

			if (requested) memcpy(&requested_align, requested, 4);
		
			if (lease) { /*ADDME: or static lease */
				if (server_id) {
					/* SELECTING State */
					if (requested && 
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
				} else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else sendNAK(&packet);
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
						else {
							/* don't know what to do!!!! */
							sendNAK(&packet);
						}
					}						
				}
				if (hostname) {
					bytes = hostname[-1];
					if (bytes >= (int) sizeof(lease->hostname))
						bytes = sizeof(lease->hostname) - 1;
					strncpy(lease->hostname, hostname, bytes);
					lease->hostname[bytes] = '\0';

					if (!is_valid_hostname(lease->hostname))
						lease->hostname[0] = '\0';

				} else
					lease->hostname[0] = '\0';
			
			/* what to do if we have no record of the client */
			} else if (server_id) {
				/* SELECTING State */
				if (requested)
					sendNAK(&packet);

			} else if (requested) {
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} else sendNAK(&packet);
				} else if (requested_align < server_config.start || 
					   requested_align > server_config.end) {
					sendNAK(&packet);
				} else {
					sendNAK(&packet);
				}
			} else if (packet.ciaddr) {
				/* RENEWING or REBINDING State */
				sendNAK(&packet);
			}
			break;
		case DHCPDECLINE:
			DEBUG(LOG_INFO,"received DECLINE");
			if (lease) {
				memset(lease->chaddr, 0, 16);
				lease->expires = uptime() + server_config.decline_time;
			}			
			break;
		case DHCPRELEASE:
			DEBUG(LOG_INFO,"received RELEASE");
			if (lease) lease->expires = uptime();
			break;
		case DHCPINFORM:
			DEBUG(LOG_INFO,"received INFORM");
			send_inform(&packet);
			break;	
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}
Exemplo n.º 9
0
void *recv_data (connection_data *connection, int timer) 
{
  char *ptr = NULL, *data = NULL;
  data_packet *data_ptr = NULL;
  handshake_packet *hs_ptr = NULL;
  fd_set listen_set;
  int result, client_index;

#ifdef _DEBUG_
  printf("Listen socket in recv-data\n");
#endif
  ptr = listen_socket(connection, timer, 0);
#ifdef _DEBUG_
  if (ptr != NULL)
    printf("ptr in recv_data is: %s\n and ptr[5] is: %c\n", ptr, ptr[5]);
#endif

  if (ptr != NULL) 
    {
      switch(atoi(&ptr[5])) 
	{
	case HANDSHAKE:
	  hs_ptr = string_to_packet(ptr, HANDSHAKE);

	  if (!is_packet(hs_ptr, HANDSHAKE) && (connection->client_id == 7 || connection->client_id == hs_ptr->client_id)) 
	    {
#ifdef _DEBUG_
	      printf("It is a handshake packet!\n");
#endif
	      if (hs_ptr->flags != RST) {
		free(hs_ptr);
		return NULL;
	      } else {
		connection_termination(connection, SERVER);
		free(hs_ptr);
		return "Terminated";
	      }
	    } 
	  else 
	    {
#ifdef _DEBUG_
	      printf("Is not a packet :(\n");
#endif
	      return NULL;
	    }
	  break;
	case DATA:
	  data_ptr = string_to_packet(ptr, DATA);

	  if (!is_packet(data_ptr, DATA)) 
	    {
#ifdef _DEBUG_
	      printf("Data packet received, containing data: %s\n", (char *)data_ptr->data);
#endif
	      client_index = data_ptr->client_id-1;
#ifdef _DEBUG_
	      printf("Client_index: %d\n", client_index);
	      printf("Last_seen_pkt[%d] = %d data_ptr->seq_nr = %d\n", client_index, connection->last_seen_pkt[client_index], data_ptr->seq_nr);
#endif
	      if (data_ptr->seq_nr > connection->last_seen_pkt[client_index])
		{
#ifdef _DEBUG_
		  printf("Data packet is newer than last seen, using...\n");
#endif
		  connection->last_seen_pkt[client_index] = data_ptr->seq_nr;
		  data = strdup(data_ptr->data);
		  free(data_ptr);
#ifdef _DEBUG_
		  printf("Last_seen_pkt[%d] = %d\n", client_index, connection->last_seen_pkt[client_index]);
#endif
		  return data;
		}
	      else 
		{
#ifdef _DEBUG_
		  printf("Packet out of order, dumping...\n");
#endif
		  return NULL;
		}
	    } 
	  else 
	    {
	      return NULL;
	    }
	default:
	  return NULL;
	}
    } 
  else
    {
      return NULL;
    }
} 
Exemplo n.º 10
0
int connect_session(connection_data *connection, char *server_ip, uint16_t server_port, uint16_t client_port) 
{
  handshake_packet syn_packet, *received_packet = NULL;
  struct sockaddr_in server, client;
  socklen_t client_len;
  int i = 0, return_value = 0;
  char *ptr = NULL;
  char *client_ip = malloc(sizeof(char) * 16);
  uint32_t sock_fd = 0;

  srand(time(NULL));
  net_init();

#ifdef _DEBUG_
  printf("Before creating socket.\n");
#endif

  if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 
    {
      perror("socket() failed");
      return -1;
    }
#ifdef _DEBUG_
  printf("After creating socket.\n");
  printf("Creating sockaddr_in to find out client ip\n");
#endif

  memset(&server, 0, sizeof(server));
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = inet_addr(server_ip);
  server.sin_port = htons(server_port);
#ifdef _DEBUG_
  printf("Using a connected UDP socket to find out client ip\n");
#endif

  if (connect(sock_fd, (struct sockaddr *)&server, sizeof(server)) < 0) 
    {
      perror("connect() failed (in trying to find out client ip)");
      return -1;
    }

  client_len = sizeof(client);
#ifdef _DEBUG_
  printf("Using getsockname() to get local IP the socket bound to\n");
#endif

  if (getsockname(sock_fd, (struct sockaddr *)&client, &client_len) < 0) 
    {
      perror("getsockname() failed when trying to find out client ip");
      return -1;
    }
#ifdef _DEBUG_
  printf("Fetching the IP address from client sockaddr struct\n");
#endif

  if (inet_ntop(AF_INET, &client.sin_addr, client_ip, 16) < 0)
    {
      perror("inet_ntop() failed to get client ip");
      return -1;
    }

  CLOSE(sock_fd);
#ifdef _DEBUG_
  printf("Client ip in buffer: %s\n", client_ip);
  printf("Before creating socket.\n");
#endif

  if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 
    {
      perror("socket() failed");
      return -1;
    }
#ifdef _DEBUG_
  printf("After creating socket.\n");
  printf("Preparing SYN packet.\n");
#endif

  syn_packet.proto_id = "herp";
  syn_packet.packet_type = HANDSHAKE;
  syn_packet.client_ip = client_ip;
  syn_packet.client_port = client_port;
  syn_packet.client_id = rand();
  syn_packet.flags = SYN;
  syn_packet.trailer = "derp";

#ifdef _DEBUG_
  printf("Converting to string.\n");
#endif
  ptr = packet_to_string(&syn_packet, HANDSHAKE);
#ifdef _DEBUG_
  printf("Setting up listening socket.\n");
#endif

  connection = create_connection_data(client_ip, client_port, syn_packet.client_id, sock_fd, connection);

#ifdef _DEBUG_
  printf("Binding socket.\n");
#endif

  if (bind(connection->sock_fd, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) 
    {
      perror("Bind() failed");
      CLOSE(connection->sock_fd);
      return -1;
    }
#ifdef _DEBUG_
  printf("Creating connection_data.\n");
#endif

  connection = create_connection_data(server_ip, server_port, syn_packet.client_id, connection->sock_fd, connection);
  connection->client_ip = client_ip;
  connection->client_port = client_port;

  for(i = 0; i < 3; i++) 
    {
#ifdef _DEBUG_
      printf("Try %d\n", i+1);
      printf("Struct data: %d %d %d socket: %d client_id: %d\n", connection->destination->sin_family, connection->destination->sin_port, connection->destination->sin_addr.s_addr, connection->sock_fd, connection->client_id);
#endif

      if (sendto(connection->sock_fd, ptr, strlen(ptr), 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) 
	{
	  perror("sendto() failed");
	  CLOSE(connection->sock_fd);
	  return -1;
	}

#ifdef _DEBUG_
      printf("Entering listening mode.\n");
#endif

      ptr = listen_socket(connection, 5, 0);

#ifdef _DEBUG_
      if (ptr != NULL)
	printf("Received string: %s\n", ptr);
#endif
      if (ptr != NULL) {

	if (atoi(&ptr[5]) == HANDSHAKE) 
	  {
#ifdef _DEBUG_
	    printf("It is a handshake packet outside recv_data!\n");
#endif
	    received_packet = (handshake_packet *)string_to_packet(ptr, HANDSHAKE);
#ifdef _DEBUG_
	    printf("ptr size %d\n", strlen(ptr));
#endif
	    if (!is_packet(received_packet, HANDSHAKE) && !strncmp(connection->client_ip, received_packet->client_ip, strlen(connection->client_ip)) && (received_packet->flags == ACK)) 
	      {
#ifdef _DEBUG_
		printf("ACK packet received: %p.\n", connection);
#endif
		connection->client_id = received_packet->client_id;
		free(client_ip);
		return 0;
	      }
	  } 
	else 
	  {
#ifdef _DEBUG_
	    printf("Is not a packet :(\n");
#endif
	    break;
	  }
      }
    } 

  fprintf(stderr, "No server responded with a ACK, stopping connection attempts...\n");
  free(client_ip);
  return 1;
}
Exemplo n.º 11
0
int end_session(connection_data *connection) 
{
  handshake_packet rst_packet, *received_packet = NULL;
  char *ptr = NULL;
  int i;

  rst_packet.proto_id = "herp";
  rst_packet.packet_type = HANDSHAKE;
  rst_packet.client_ip = connection->client_ip;
  rst_packet.client_port = connection->client_port;
  rst_packet.client_id = connection->client_id;
  rst_packet.flags = RST;
  rst_packet.trailer = "derp";

  ptr = packet_to_string(&rst_packet, HANDSHAKE);

  if (sendto(connection->sock_fd, ptr, strlen(ptr), 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) 
    {
      perror("sendto() failed");
      CLOSE(connection->sock_fd);
      return -1;
    }

  for (i = 0; i < 2; i++)
    {
#ifdef _DEBUG_
      printf("Listening for ACK packet from termination.\n");
#endif

      ptr = listen_socket(connection, 3, 0);

#ifdef _DEBUG_
      if (ptr != NULL) {
	printf("ptr size %d\n", strlen(ptr));
	printf("packet type: %d ptr: %s\n", atoi(&ptr[5]), ptr);
      }
#endif
      if (ptr != NULL) {

        if (atoi(&ptr[5]) == HANDSHAKE) 
          {
#ifdef _DEBUG_
            printf("Converting from string to packet.\n");
#endif
            received_packet = (handshake_packet *)string_to_packet (ptr, HANDSHAKE);
#ifdef _DEBUG_
            printf("It is a handshake packet outside recv_data()!\n");
#endif

            if (!is_packet(received_packet, HANDSHAKE) && (received_packet->flags == ACK)) 
              {
#ifdef _DEBUG_
                printf("ACK Packet received.\n");
#endif
                connection_termination(connection, CLIENT);
                break;
              } 
          }
      }
    }

  free(received_packet);
  return 0;  
}
Exemplo n.º 12
0
int accept_session (connection_data *connection, uint16_t port, int client_id) 
{
  handshake_packet ack_packet, *received_packet = NULL;
  static int first_time = 1;
  static uint16_t sock_fd;
  char *ptr = NULL;

  if (first_time) 
    {
#ifdef _DEBUG_
      printf("Inside a first_time only\n");
#endif
      net_init();
#ifdef _DEBUG_
      printf("Before creating socket.\n");
#endif

      if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) 
	{
	  perror("socket() failed");
	  return -1;
	}
#ifdef _DEBUG_
      printf("After creating socket.\n");
#endif
    }

  connection = create_connection_data("0.0.0.0", port, 0, sock_fd, connection);

  if (first_time) 
    {
#ifdef _DEBUG_
      printf("Setting up listening socket.\n");
      printf("Binding socket.\n");
#endif
      if (bind(sock_fd, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) 
	{
	  perror("Bind() failed");
	  CLOSE(sock_fd);
	  return -1;
	}
      first_time = 0;
    }

  while(1) 
    {
#ifdef _DEBUG_
      printf("Listening for SYN packet.\n");
      printf("connection->sock_fd: %d\n", connection->sock_fd);
#endif
      ptr = listen_socket(connection, 60, 0);
#ifdef _DEBUG_
      printf("Received string: %s\n", ptr);
#endif
      if (ptr != NULL) {

        if (atoi(&ptr[5]) == HANDSHAKE) 
          {
#ifdef _DEBUG_
            printf("Converting from string to packet.\n");
#endif
            received_packet = (handshake_packet *)string_to_packet(ptr, HANDSHAKE);
#ifdef _DEBUG_
            printf("ptr size %d\n", strlen(ptr));
            printf("It is a handshake packet outside recv_data!\n");
            printf("Content: %s %u %s %u %u %s\n", received_packet->proto_id, received_packet->packet_type, received_packet->client_ip, received_packet->client_port, received_packet->flags, received_packet->trailer);
#endif

            if (!is_packet(received_packet, HANDSHAKE) && received_packet->flags == SYN) 
              {
#ifdef _DEBUG_
                printf("SYN Packet received.\n");
#endif
                break;
              }
            else if (!is_packet(received_packet, HANDSHAKE) && received_packet->flags == RST) 
              {
                connection_termination(connection, SERVER);
                return 1;
              }
          }
      }
    }
#ifdef _DEBUG_
  printf("Preparing ACK packet.\n");
#endif

  ack_packet.proto_id = "herp";
  ack_packet.packet_type = HANDSHAKE;
  ack_packet.client_ip = received_packet->client_ip;
  ack_packet.client_port = received_packet->client_port;
  ack_packet.client_id = client_id;
  ack_packet.flags = ACK;
  ack_packet.trailer = "derp";
#ifdef _DEBUG_
  printf("Creating connection_data struct.\n");
#endif

  connection = create_connection_data(received_packet->client_ip, received_packet->client_port, client_id, connection->sock_fd, connection);
#ifdef _DEBUG_
  printf("Converting packet_to_string.\n");
#endif

  ptr = packet_to_string(&ack_packet, HANDSHAKE);

#ifdef _DEBUG_
  printf("Sending ACK packet.\n");
#endif

  if (sendto(connection->sock_fd, ptr, strlen(ptr), 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) 
    {
      perror("sendto() failed");
      CLOSE(connection->sock_fd);
      return -1;
    }
#ifdef _DEBUG_
  printf("pointer address %p\n", connection);
#endif
  free(received_packet);
  free(ptr);
  return 0;
}