예제 #1
0
Routes* getRoutes(Graph* graph, int vertex)
{
	if (graph->vertices > 32)
	{
		return NULL;
	}
	Routes *routes = createRoutes(graph->vertices);
	unsigned int endMask = 0;
	endMask = ~endMask;
	endMask >>= (32 - graph->vertices);
	unsigned int visited = 0;
	routes->weight[vertex] = 0;
	routes->from[vertex] = vertex;
	int current = vertex;
	while ((visited != endMask) && (current != 0))
	{
		int i = current;
		for (int j = 1; j <= graph->vertices; j++)
		{
			if (graph->a[i][j] == 0)
			{
				continue;
			}
			int weight = routes->weight[i] + graph->a[i][j];
			unsigned int jMask = 1;
			jMask <<= j - 1;
			if (!(jMask & visited) && ((weight < routes->weight[j]) || (routes->weight[j] == 0)))
			{
				routes->weight[j] = weight;
				routes->from[j] = current;
			}
		}
		unsigned int mask = 1;
		mask <<= current - 1;
		visited |= mask;
		current = getNearestVertex(routes, visited);
	}
	return routes;
}
예제 #2
0
int main(int argc, char **argv) {
    // ------------------------------------------------------------------------
    // Handle commandline arguments
    if (argc < 5) {
        printf("usage: emulator -p <port> -f <filename>\n");
        exit(1);
    }

    char *portStr    = NULL;
    const char *filename   = NULL;

    int cmd;
    while ((cmd = getopt(argc, argv, "p:f:")) != -1) {
        switch(cmd) {
            case 'p': portStr   = optarg; break;
            case 'f': filename  = optarg; break;
            case '?':
                if (optopt == 'p' || optopt == 'f')
                    fprintf(stderr, "Option -%c requires an argument.\n", optopt);
                else if (isprint(optopt))
                    fprintf(stderr, "Unknown option -%c.\n", optopt);
                else
                    fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt);
                exit(EXIT_FAILURE);
            break;
            default: 
                printf("Unhandled argument: %d\n", cmd);
                exit(EXIT_FAILURE); 
        }
    }

    printf("Port        : %s\n", portStr);
    printf("File Name   : %s\n", filename);

    // Convert program args to values
    int emulPort  = atoi(portStr);
    int maxTime = 1500;
    int minTime = 500;

    // Validate the argument values
    if (emulPort <= 1024 ||emulPort >= 65536)
        ferrorExit("Invalid emul port");
    puts("");

    srand(time(NULL));
    initLog("log_file.txt");
	
    // ------------------------------------------------------------------------
    // Setup emul address info 
    struct addrinfo ehints;
    bzero(&ehints, sizeof(struct addrinfo));
    ehints.ai_family   = AF_INET;
    ehints.ai_socktype = SOCK_DGRAM;
    ehints.ai_flags    = AI_PASSIVE;
    
    char localhost[80];
    gethostname(localhost, sizeof(localhost));
    
    // Get the emul's address info
    struct addrinfo *emulinfo;
    int errcode = getaddrinfo(localhost, portStr, &ehints, &emulinfo);
    if (errcode != 0) {
        fprintf(stderr, "emul getaddrinfo: %s\n", gai_strerror(errcode));
        exit(EXIT_FAILURE);
    }

    // Loop through all the results of getaddrinfo and try to create a socket for emul
    int sockfd;
    struct addrinfo *sp;
    for(sp = emulinfo; sp != NULL; sp = sp->ai_next) {
        // Try to create a new socket
        sockfd = socket(sp->ai_family, sp->ai_socktype, sp->ai_protocol);
        if (sockfd == -1) {
            perror("Socket error");
            continue;
        }
		
		// Try to bind the socket
        if (bind(sockfd, sp->ai_addr, sp->ai_addrlen) == -1) {
            perror("Bind error");
            close(sockfd);
            continue;
        }
		
        break;
    }
    if (sp == NULL) perrorExit("Send socket creation failed");
    else            printf("emul socket created.\n");

	struct sockaddr_in *tmp = (struct sockaddr_in *)sp->ai_addr;
	unsigned long eIpAddr = tmp->sin_addr.s_addr;
	//printf("eIpAddr: %lu\n", eIpAddr);
  initTable(filename, tmp);

  exit(0);
  // ------------------------------------------------------------------------
	// The Big Loop of DOOM

	struct sockaddr_in *nextSock;
  int shouldForward;
	fd_set fds;
	
  struct timespec *tv = malloc(sizeof(struct timespec));
	tv->tv_sec = (long) 0;
	tv->tv_nsec = 0;
  int retval = 0;
	int numRecv = 0;
  int routesMade = 0;
	unsigned long long start;
  struct packet *dpkt;
  struct ip_packet *pkt = malloc(sizeof(struct ip_packet));
	void *msg = malloc(sizeof(struct ip_packet));
  for (;;) {
		FD_ZERO(&fds);
		FD_SET(sockfd, &fds);
		start = getTimeMS();
		retval = pselect(sockfd + 1, &fds, NULL, NULL, tv, NULL);
	
		// ------------------------------------------------------------------------
		// receiving half
        
		if (retval > 0 /*&& routesMade == 1*/) {
			// Receive and forward packet
			printf("retval > 0\n");
			bzero(msg, sizeof(struct ip_packet));
			size_t bytesRecvd = recvfrom(sockfd, msg, sizeof(struct ip_packet), 0, NULL, NULL);
			if (bytesRecvd == -1) {
				perror("Recvfrom error");
				fprintf(stderr, "Failed/incomplete receive: ignoring\n");
				continue;
			}
			
			// Deserialize the message into a packet 
			bzero(pkt, sizeof(struct ip_packet));
			deserializeIpPacket(msg, pkt);
			dpkt = (struct packet *)pkt->payload;
			printIpPacketInfo(pkt, NULL);
      
      // Check packet type to see if any action needs to be taken
      nextSock = malloc(sizeof(struct sockaddr_in));
      if (dpkt->type == 'T') {
        if (dpkt->len == 0) {
          bzero(nextSock, sizeof(struct sockaddr_in));
          shouldForward = 1;
          nextSock->sin_family = AF_INET;
					nextSock->sin_addr.s_addr = htonl(pkt->src);
					nextSock->sin_port = htons(pkt->srcPort);
          pkt->src = eIpAddr;
          pkt->srcPort = emulPort;
        }
        else {
          dpkt->len--;
          shouldForward = nextHop(pkt, nextSock);
        }
      }
      else if (dpkt->type == 'S') {
        /*if ((pkt->dest == eIpAddr && pkt->destPort == emulPort) || dpkt->len == 0) {
          dpkt = createNeighborPkt();
          bzero(pkt, sizeof(struct ip_packet));
          pkt->length = dpkt->len + HEADER_SIZE;
          pkt->priority = 0;
          memcpy(pkt->payload, dpkt, sizeof(struct packet));
          
        }*/
        if (updateLSP(pkt)) {
          floodLSP(sockfd, tmp, pkt);
        }
        shouldForward = 0;
        routesMade = 0;
      }
      else {
        shouldForward = nextHop(pkt, nextSock);
      }
      // Forward the packet if there is an entry for it
			if (shouldForward)	{
        printf("send packet\n");
        //printf("socket is %lu  %u", nextSock->sin_addr.s_addr, nextSock->sin_port);
        sendIpPacketTo(sockfd, pkt, (struct sockaddr*)nextSock);
        free(nextSock);
			}
			else {
				logP(pkt, "No forwarding entry found");
			}
			
      // update timespec
			long sec = tv->tv_sec - (long)((getTimeMS() - start) / 1000);
			long nsec = tv->tv_nsec - (long)(1000000 * ((getTimeMS() - start) % 1000));
			if (nsec < 0) {
				nsec = 1000000 * 1000 + nsec;
				sec--;
				
			}
			if (sec < 0 || !numRecv) {
					sec = 0;
					nsec = 0;
			}
			tv->tv_sec = sec;
			tv->tv_nsec = nsec;
		}
		if (retval == 0 || routesMade == 0) {
			// ------------------------------------------------------------------------
			// refresh forward table
			printf("retval == 0\n");
			if (retval == 0) {
        floodLSP(sockfd, tmp, NULL);
      }
      routesMade = createRoutes(tmp);
      
      int delay = minTime + (rand() % (maxTime - minTime));
      tv->tv_sec = (long)delay / 1000;
      tv->tv_nsec = (long)(delay % 1000) * 1000000;
		}
		else {
			//printf("Sockfd = %d\n", sockfd);
			//printf("tv%d  delay=%li s   %li us\n", x, tv->tv_sec, tv->tv_nsec);
			perrorExit("Select()");
		}
  }
	// Cleanup packets
  free(pkt);
  free(msg);
}
예제 #3
0
int main(int argc, char **argv) {
    // ------------------------------------------------------------------------
    // Handle commandline arguments
    if (argc != 5) {
        printf("usage: emulator -p <port> -f <filename>\n");
        exit(1);
    }

    char *portStr     = NULL;
    char *filename    = NULL;

    int cmd;
    while ((cmd = getopt(argc, argv, "p:f:")) != -1) {
        switch(cmd) {
          case 'p': portStr      = optarg; break;
          case 'f': filename     = optarg; break;
          case '?':
                    if (optopt == 'p' || optopt == 'f')
                        fprintf(stderr, "Option -%c requires an argument.\n", optopt);
                    else if (isprint(optopt))
                        fprintf(stderr, "Unknown option -%c.\n", optopt);
                    else
                        fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt);
                    exit(EXIT_FAILURE);
                    break;
          default: 
                    printf("Unhandled argument: %d\n", cmd);
                    exit(EXIT_FAILURE); 
        }
    }

    printf("Port           : %s\n", portStr);
    printf("Filename       : %s\n", filename);

    // Convert program args to values
    int port         = atoi(portStr);

    // Validate the argument values
    if (port < 1 || port > 65536)
        ferrorExit("Invalid port");
    puts("");


    // Read network topology
    struct entry **topology = readtopology(filename);
    printTopology(topology);

    // Create network routes from topology
    createRoutes(topology);


    // TODO: this is temporary, need to get sender address info from fwd table
    // Setup sender address info 
    struct addrinfo ehints;
    bzero(&ehints, sizeof(struct addrinfo));
    ehints.ai_family   = AF_INET;
    ehints.ai_socktype = SOCK_DGRAM;
    ehints.ai_flags    = 0;

    // Setup emu sending socket
    struct sockaddr_in emuaddr;

    int sockfd;

    if( (sockfd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1){
        perrorExit("Socket error");
    }

    emuaddr.sin_family = AF_INET;
    emuaddr.sin_port = htons(port);
    emuaddr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(emuaddr.sin_zero), 8);


    if (bind(sockfd, (struct sockaddr*)&emuaddr, sizeof(emuaddr)) == -1) {
        close(sockfd);
        perrorExit("Bind error");
    }

    printf("Emulator socket created on port:%d\n", port );

    //-------------------------------------------------------------------------
    // BEGIN NETWORK EMULATION LOOP
    puts("Emulator waiting for packets...\n");

    struct sockaddr_in recvAddr;

    socklen_t recvLen = sizeof(recvAddr);
    //socklen_t sendLen = sizeof(sendAddr);
    // HACK: Don't like hard coding this, but don't know any other way
    size_t MAX_HOST_LEN = 256;
    char name[MAX_HOST_LEN];
    gethostname(name, MAX_HOST_LEN);
    //Need to just get lowest level dns name i.e. mumble-30

    while (1) {
        void *msg = malloc(sizeof(struct packet));
        bzero(msg, sizeof(struct packet));
        size_t bytesRecvd;
        bytesRecvd = recvfrom(sockfd, msg, sizeof(struct packet), 0,
                              (struct sockaddr *)&recvAddr, &recvLen);
        if (bytesRecvd != -1) {
            //printf("Received %d bytes\n", (int)bytesRecvd);
            // Deserialize the message into a packet 
            struct packet *pkt = malloc(sizeof(struct packet));
            bzero(pkt, sizeof(struct packet));
            deserializePacket(msg, pkt);

            struct addrinfo entryHints;
            bzero(&entryHints, sizeof(struct addrinfo));
            entryHints.ai_family   = AF_INET;
            entryHints.ai_socktype = SOCK_DGRAM;
            entryHints.ai_flags    = 0;

        }	
    }
    if (close(sockfd) == -1) perrorExit("Close error");
    else                     puts("Connection closed.\n");

    // All done!
    exit(EXIT_SUCCESS);


}