123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- #include <stdio.h>
- #include <stdint.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include "bootp.h"
- static void usage(int argc, char **argv)
- {
- const char *name = argc ? argv[0] : "boot-it";
- printf("usage: %s [-H <bind to this host>] [-P <bind to this port>]\n",
- name);
- exit(EXIT_FAILURE);
- }
- int main(int argc, char **argv)
- {
- int c;
- int errct = 0;
- const char *bind_host = NULL;
- const char *bind_port = BOOTP_SERVER_PORT;
- while ((c = getopt(argc, argv, ":H:p:h")) != -1) {
- switch (c) {
- case 'H':
- bind_host = optarg;
- break;
- case 'p':
- bind_port = optarg;
- break;
- case ':':
- fprintf(stderr, "option -%c requries an operand\n", optopt);
- errct++;
- break;
- case '?':
- fprintf(stderr, "unrecognized option -%c\n", optopt);
- errct++;
- break;
- case 'h':
- usage(argc, argv);
- }
- }
- if (errct)
- usage(argc, argv);
- struct addrinfo hint = {
- .ai_family = AF_INET,
- .ai_socktype = SOCK_DGRAM,
- .ai_flags = AI_PASSIVE,
- };
- struct addrinfo *res;
- int s = getaddrinfo(bind_host, bind_port, &hint, &res);
- if (s != 0) {
- fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
- exit(EXIT_FAILURE);
- }
- int sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (sock == -1) {
- fprintf(stderr, "could get socket: %s\n", strerror(errno));
- return 1;
- }
- s = bind(sock, res->ai_addr, res->ai_addrlen);
- if (!s) {
- fprintf(stderr, "bind failed: %s\n", strerror(errno));
- return 1;
- }
- freeaddrinfo(res);
- for (;;) {
- struct sockaddr_storage peer_addr;
- socklen_t peer_addr_len = sizeof(peer_addr);
- char buf[512];
- ssize_t nread = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&peer_addr, &peer_addr_len);
- if (nread == -1)
- continue;
- char host[NI_MAXHOST], service[NI_MAXSERV];
- s = getnameinfo((struct sockaddr *)&peer_addr,
- peer_addr_len, host, NI_MAXHOST,
- service, NI_MAXSERV, NI_NUMERICSERV|NI_NUMERICHOST);
- if (!s) {
- fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
- strncpy(host, "(unknown host)", sizeof(host));
- strncpy(service, "(unknown service)", sizeof(service));
- }
- printf("recv %zd bytes from %s:%s\n", nread, host, service);
- }
- return 0;
- }
|