Example #1
0
static FILE *open_config_file(char **filename) {
	assert(filename != NULL);

	char *config = getenv("MACSPOOF_CONFIG");
	if (config != NULL) {
		*filename = "<none>";
		FILE *file = fmemopen(config, strlen(config), "r");
		if (file == NULL) perror_die("fmemopen");
		return file;
	}

	*filename = getenv("MACSPOOF_CONFIG_FILE");
	if (*filename != NULL) {
		FILE *file = fopen(*filename, "r");
		if (file == NULL) perror_die("fopen");
		return file;
	}

	*filename = "~/.macspoofrc";
	FILE *file = fopen(*filename, "r");
	if (file != NULL) return file;

	*filename = MACSPOOF_ETCDIR "/macspoof.conf";
	file = fopen(*filename, "r");
	if (file == NULL) {
		perror("fopen");
		die("Cannot open any config file.");
	}
	return file;
}
Example #2
0
int main(int argc, const char** argv) {
  setvbuf(stdout, NULL, _IONBF, 0);

  int portnum = 9988;
  if (argc >= 2) {
    portnum = atoi(argv[1]);
  }
  printf("Listening on port %d\n", portnum);

  int sockfd = listen_inet_socket(portnum);
  struct sockaddr_in peer_addr;
  socklen_t peer_addr_len = sizeof(peer_addr);

  int newsockfd = accept(sockfd, (struct sockaddr*)&peer_addr, &peer_addr_len);
  if (newsockfd < 0) {
    perror_die("ERROR on accept");
  }
  report_peer_connected(&peer_addr, peer_addr_len);

  // Set nonblocking mode on the socket.
  int flags = fcntl(newsockfd, F_GETFL, 0);
  if (flags == -1) {
    perror_die("fcntl F_GETFL");
  }

  if (fcntl(newsockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
    perror_die("fcntl F_SETFL O_NONBLOCK");
  }

  while (1) {
    uint8_t buf[1024];
    printf("Calling recv...\n");
    int len = recv(newsockfd, buf, sizeof buf, 0);
    if (len < 0) {
      if (errno == EAGAIN || errno == EWOULDBLOCK) {
        // No data on the socket; sleep a bit and re-try recv().
        usleep(200 * 1000);
        continue;
      }
      perror_die("recv");
    } else if (len == 0) {
      printf("Peer disconnected; I'm done.\n");
      break;
    }
    printf("recv returned %d bytes\n", len);
  }

  close(newsockfd);
  close(sockfd);

  return 0;
}
Example #3
0
xmlelf_t * xmlelf_create_info( elf_t * elf , char * name )
{
   xmlDocPtr  doc;
   xmlelf_t * ret;

   if(!elf||!name)
      error_ret("null args",NULL);

   if(!(ret = calloc(1,sizeof(*ret))))
      perror_die("calloc()",1);

   if(!(doc = xmlNewDoc("1.0"))){
      free(ret);
      error_ret("can't get doc",NULL);
   }

   if(!(doc->root= xmlNewDocNode(doc,NULL,"elf",NULL))){
      xmlFreeDoc(doc);
      free(ret);
      error_ret("Can't create node",NULL);
   }

   xmlelf_set_elf( ret , elf );
   ret->name = strdup(name);
   ret->doc = doc;
   return(ret);
}
Example #4
0
static void install_term_and_int_handlers() {
  struct sigaction sa;
  sa.sa_handler = on_signal;
  sa.sa_flags = 0;
  sigemptyset(&sa.sa_mask);

  if (sigaction(SIGINT, &sa, NULL))
    perror_die("could not catch SIGINT");

  if (sigaction(SIGTERM, &sa, NULL))
    perror_die("could not catch SIGTERM");

  sa.sa_handler = on_alarm;
  if (sigaction(SIGALRM, &sa, NULL))
    perror_die("could not catch SIGALRM");
}
Example #5
0
void *my_realloc(void *ptr, size_t size)
{
  void *result;
  if ((result = realloc(ptr, size)) == NULL)
    perror_die("malloc");
  return result;
}
Example #6
0
void *my_malloc(size_t size)
{
  void *result;
  if ((result = malloc(size)) == NULL)
    perror_die("malloc");
  bzero(result, size);
  return result;
}
Example #7
0
static char *mkconfig(const char *fmt, ...) {
	char *name = strdup("macspoof_test.XXXXXXXX");
	if (name == NULL) perror_die("strdup");
	int fd = mkstemp(name);
	if (fd == -1) perror_die("mkstemp");
	tempfiles = g_slist_prepend(tempfiles, name);
	FILE *file = fdopen(fd, "r+");
	if (file == NULL) perror_die("fdopen");

	va_list ap;
	va_start(ap, fmt);
	if (vfprintf(file, fmt, ap) == -1) perror_die("vfprintf");
	va_end(ap);

	if (fclose(file) == EOF) perror_die("fclose");

	return name;
}
Example #8
0
static void read_config(void) {
	char *filename = NULL;
	FILE *file = open_config_file(&filename);

	if (config_read(config, file) != CONFIG_TRUE)
		die("%s:%d %s", filename, config_error_line(config), config_error_text(config));

	if (fclose(file) == EOF) perror_die("fclose");
}
Example #9
0
int main(int argc, const char** argv) {
  setvbuf(stdout, NULL, _IONBF, 0);

  int portnum = 9988;
  if (argc >= 2) {
    portnum = atoi(argv[1]);
  }
  printf("Listening on port %d\n", portnum);

  int sockfd = listen_inet_socket(portnum);
  struct sockaddr_in peer_addr;
  socklen_t peer_addr_len = sizeof(peer_addr);

  int newsockfd = accept(sockfd, (struct sockaddr*)&peer_addr, &peer_addr_len);
  if (newsockfd < 0) {
    perror_die("ERROR on accept");
  }
  report_peer_connected(&peer_addr, peer_addr_len);

  while (1) {
    uint8_t buf[1024];
    printf("Calling recv...\n");
    int len = recv(newsockfd, buf, sizeof buf, 0);
    if (len < 0) {
      perror_die("recv");
    } else if (len == 0) {
      printf("Peer disconnected; I'm done.\n");
      break;
    }
    printf("recv returned %d bytes\n", len);
  }

  close(newsockfd);
  close(sockfd);

  return 0;
}
Example #10
0
xmlelf_t * xmlelf_open_info( elf_t * elf , char * name )
{
   xmlDocPtr  doc;
   xmlelf_t * ret;

   if(!elf||!name)
      error_ret("null args",NULL);

   if(!(ret = calloc(1,sizeof(*ret))))
      perror_die("calloc()",1);

   if(!(doc = xmlParseDoc("1.0"))){
      free(ret);
      error_ret("can't get doc",NULL);
   }
   return(ret);
}
Example #11
0
/*
 * Open an existing info file.  
 */
xmlelf_t * xmlelf_open_info( elf_t * elf , char * name )
{
   xmlDocPtr  doc;
   xmlelf_t * ret;

   if(!elf||!name)
      error_ret("null args",NULL);

   if(!(ret = calloc(1,sizeof(*ret))))
      perror_die("calloc()",1);

   if(!(doc = xmlParseFile(name))){
      free(ret);
      error_ret("can't get doc",NULL);
   }
   ret->elf  = elf;
   ret->doc  = doc;
   ret->root = doc->children;
   ret->name = strdup(name);
   return(ret);
}
Example #12
0
fd_status_t on_peer_ready_recv(int sockfd) {
  assert(sockfd < MAXFDs);
  peer_state_t* peerstate = &global_state[sockfd];

  if (peerstate->state == INITIAL_ACK ||
      peerstate->sendptr < peerstate->sendbuf_end) {
    // Until the initial ACK has been sent to the peer, there's nothing we
    // want to receive. Also, wait until all data staged for sending is sent to
    // receive more data.
    return fd_status_W;
  }

  uint8_t buf[1024];
  int nbytes = recv(sockfd, buf, sizeof buf, 0);
  if (nbytes == 0) {
    // The peer disconnected.
    return fd_status_NORW;
  } else if (nbytes < 0) {
    if (errno == EAGAIN || errno == EWOULDBLOCK) {
      // The socket is not *really* ready for recv; wait until it is.
      return fd_status_R;
    } else {
      perror_die("recv");
    }
  }
  bool ready_to_send = false;
  for (int i = 0; i < nbytes; ++i) {
    switch (peerstate->state) {
    case INITIAL_ACK:
      assert(0 && "can't reach here");
      break;
    case WAIT_FOR_MSG:
      if (buf[i] == '^') {
        peerstate->state = IN_MSG;
      }
      break;
    case IN_MSG:
      if (buf[i] == '$') {
        peerstate->state = WAIT_FOR_MSG;
      } else {
        assert(peerstate->sendbuf_end < SENDBUF_SIZE);
        peerstate->sendbuf[peerstate->sendbuf_end++] = buf[i] + 1;
        ready_to_send = true;
      }
      break;
    }
  }
  // Report reading readiness iff there's nothing to send to the peer as a
  // result of the latest recv.
  return (fd_status_t){.want_read = !ready_to_send,
                       .want_write = ready_to_send};
}

fd_status_t on_peer_ready_send(int sockfd) {
  assert(sockfd < MAXFDs);
  peer_state_t* peerstate = &global_state[sockfd];

  if (peerstate->sendptr >= peerstate->sendbuf_end) {
    // Nothing to send.
    return fd_status_RW;
  }
  int sendlen = peerstate->sendbuf_end - peerstate->sendptr;
  int nsent = send(sockfd, peerstate->sendbuf, sendlen, 0);
  if (nsent == -1) {
    if (errno == EAGAIN || errno == EWOULDBLOCK) {
      return fd_status_W;
    } else {
      perror_die("send");
    }
  }
  if (nsent < sendlen) {
    peerstate->sendptr += nsent;
    return fd_status_W;
  } else {
    // Everything was sent successfully; reset the send queue.
    peerstate->sendptr = 0;
    peerstate->sendbuf_end = 0;

    // Special-case state transition in if we were in INITIAL_ACK until now.
    if (peerstate->state == INITIAL_ACK) {
      peerstate->state = WAIT_FOR_MSG;
    }

    return fd_status_R;
  }
}
Example #13
0
int main(int argc, const char** argv) {
  setvbuf(stdout, NULL, _IONBF, 0);

  int portnum = 9090;
  if (argc >= 2) {
    portnum = atoi(argv[1]);
  }
  printf("Serving on port %d\n", portnum);

  int listener_sockfd = listen_inet_socket(portnum);
  make_socket_non_blocking(listener_sockfd);

  int epollfd = epoll_create1(0);
  if (epollfd < 0) {
    perror_die("epoll_create1");
  }

  struct epoll_event accept_event;
  accept_event.data.fd = listener_sockfd;
  accept_event.events = EPOLLIN;
  if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listener_sockfd, &accept_event) < 0) {
    perror_die("epoll_ctl EPOLL_CTL_ADD");
  }

  struct epoll_event* events = calloc(MAXFDS, sizeof(struct epoll_event));
  if (events == NULL) {
    die("Unable to allocate memory for epoll_events");
  }

  while (1) {
    int nready = epoll_wait(epollfd, events, MAXFDS, -1);
    for (int i = 0; i < nready; i++) {
      if (events[i].events & EPOLLERR) {
        perror_die("epoll_wait returned EPOLLERR");
      }

      if (events[i].data.fd == listener_sockfd) {
        // The listening socket is ready; this means a new peer is connecting.

        struct sockaddr_in peer_addr;
        socklen_t peer_addr_len = sizeof(peer_addr);
        int newsockfd = accept(listener_sockfd, (struct sockaddr*)&peer_addr,
                               &peer_addr_len);
        if (newsockfd < 0) {
          if (errno == EAGAIN || errno == EWOULDBLOCK) {
            // This can happen due to the nonblocking socket mode; in this
            // case don't do anything, but print a notice (since these events
            // are extremely rare and interesting to observe...)
            printf("accept returned EAGAIN or EWOULDBLOCK\n");
          } else {
            perror_die("accept");
          }
        } else {
          make_socket_non_blocking(newsockfd);
          if (newsockfd >= MAXFDS) {
            die("socket fd (%d) >= MAXFDS (%d)", newsockfd, MAXFDS);
          }

          fd_status_t status =
              on_peer_connected(newsockfd, &peer_addr, peer_addr_len);
          struct epoll_event event = {0};
          event.data.fd = newsockfd;
          if (status.want_read) {
            event.events |= EPOLLIN;
          }
          if (status.want_write) {
            event.events |= EPOLLOUT;
          }

          if (epoll_ctl(epollfd, EPOLL_CTL_ADD, newsockfd, &event) < 0) {
            perror_die("epoll_ctl EPOLL_CTL_ADD");
          }
        }
      } else {
        // A peer socket is ready.
        if (events[i].events & EPOLLIN) {
          // Ready for reading.
          int fd = events[i].data.fd;
          fd_status_t status = on_peer_ready_recv(fd);
          struct epoll_event event = {0};
          event.data.fd = fd;
          if (status.want_read) {
            event.events |= EPOLLIN;
          }
          if (status.want_write) {
            event.events |= EPOLLOUT;
          }
          if (event.events == 0) {
            printf("socket %d closing\n", fd);
            if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL) < 0) {
              perror_die("epoll_ctl EPOLL_CTL_DEL");
            }
            close(fd);
          } else if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event) < 0) {
            perror_die("epoll_ctl EPOLL_CTL_MOD");
          }
        } else if (events[i].events & EPOLLOUT) {
          // Ready for writing.
          int fd = events[i].data.fd;
          fd_status_t status = on_peer_ready_send(fd);
          struct epoll_event event = {0};
          event.data.fd = fd;

          if (status.want_read) {
            event.events |= EPOLLIN;
          }
          if (status.want_write) {
            event.events |= EPOLLOUT;
          }
          if (event.events == 0) {
            printf("socket %d closing\n", fd);
            if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL) < 0) {
              perror_die("epoll_ctl EPOLL_CTL_DEL");
            }
            close(fd);
          } else if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event) < 0) {
            perror_die("epoll_ctl EPOLL_CTL_MOD");
          }
        }
      }
    }
  }

  return 0;
}
Example #14
0
static void set_text(YYSTYPE *yylval, const char *text)
{
  if ((yylval->text = strdup(text)) == NULL)
    perror_die("strdup");
}