示例#1
0
文件: econsole.c 项目: jelaas/egetty
int main(int argc, char **argv)
{
	struct sockaddr_ll from;
	socklen_t fromlen = sizeof(from);
	char *device = "eth0", *ps;
	uint8_t *buf, *p;
	int n, i, err=0;
	unsigned int len;
	struct sk_buff *skb;

	conf.ifindex=-1;
	conf.debug = 0;

	if(jelopt(argv, 'h', "help", NULL, &err)) {
		printf("econsole [DEV] [CONSOLE] [DESTMAC] [(scan|debug)]\n"); 
		exit(0);
	}
	argc = jelopt_final(argv, &err);
	if(err) {
		printf("Syntax error in arguments.\n");
		exit(2);
	}

	while(--argc > 0) {
		if(strcmp(argv[argc], "scan")==0) {
			printf("Scanning for econsoles\n");
			conf.scan = 1;
			continue;
		}
		if(strcmp(argv[argc], "debug")==0) {
			printf("Debug mode\n");
			conf.debug++;
			continue;
		}
		if( (strlen(argv[argc]) < 3) && isdigit(*argv[argc])) {
			conf.console = atoi(argv[argc]);
			continue;
		}
		if(strchr(argv[argc], ':' )) {
			unsigned int a;
			ps = argv[argc];
			for(i=0;i<6;i++) {
				sscanf(ps, "%x", &a);
				conf.dest.sll_addr[i] = a;
				ps = strchr(ps, ':');
				if(!ps) break;
				ps++;
			}
			conf.ucast = 1;
			continue;
		} else {
			device = argv[argc];
		}
	}
	
	conf.devsocket = devsocket();
	
	while(set_flag(device, (IFF_UP | IFF_RUNNING))) {
		printf("Waiting for interface to be available\n");
		sleep(1);
	}
	
	if(device)
	{
		conf.ifindex = if_nametoindex(device);
		if(!conf.ifindex)
		{
			fprintf(stderr, "no such device %s\n", device);
			exit(1);
		}
	}

	conf.s = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_EGETTY));
	if(conf.s == -1)
	{
		fprintf(stderr, "socket(): %s\n", strerror(errno));
		exit(1);
	}


	if(conf.ifindex >= 0)
	{
		struct sockaddr_ll addr;
		memset(&addr, 0, sizeof(addr));
		
		addr.sll_family = AF_PACKET;
		addr.sll_protocol = htons(ETH_P_EGETTY);
		addr.sll_ifindex = conf.ifindex;
		
		if(bind(conf.s, (const struct sockaddr *)&addr, sizeof(addr)))
		{
			fprintf(stderr, "bind failed: %s\n", strerror(errno));
			exit(1);
		}
	}

	if(!conf.scan) {
		terminal_settings();
		signals_init();
		winch_handler(0);
		fprintf(stderr, "Use CTRL-] to close connection.\n");
	}

	skb = alloc_skb(1500);

	if(conf.scan)
		console_scan(conf.s, conf.ifindex, skb);

	while(1)
	{
		struct pollfd fds[2];

		fds[0].fd = 0;
		fds[0].events = POLLIN;
		fds[0].revents = 0;
		
		fds[1].fd = conf.s;
		fds[1].events = POLLIN;
		fds[1].revents = 0;

		n = poll(fds, 2, -1);
		if(n == 0) {
			printf("timeout\n");
			continue;
		}

		if(fds[0].revents & POLLIN) {
			skb_reset(skb);
			skb_reserve(skb, 4);
			buf = skb_put(skb, 0);
			n = read(0, buf, skb_tailroom(skb));
			if(n == -1) {
				fprintf(stderr, "read() failed\n");
				exit(1);
			}
			if(n == 0) {
				fprintf(stderr, "read() EOF\n");
				exit(0);
			}
			buf[n] = 0;
			if(conf.debug) printf("read %d bytes from stdin\n", n);
			if(conf.debug > 1) printf("buf[0] == %d\n", buf[0]);
			if(n==1 && buf[0] == 0x1d) {
				console_hup(conf.s, conf.ifindex);
				tcsetattr(0, TCSANOW, &conf.term);
				exit(0);
			}
			skb_put(skb, n);
			if(!conf.scan) console_put(conf.s, conf.ifindex, skb);
		}
		if(fds[1].revents) {
			skb_reset(skb);
			buf = skb_put(skb, 0);
			n = recvfrom(conf.s, buf, skb_tailroom(skb), 0, (struct sockaddr *)&from, &fromlen);
			if(n == -1) {
				fprintf(stderr, "recvfrom() failed. ifconfig up?\n");
				continue;
			}
			skb_put(skb, n);

			if(conf.ucast)
				if(memcmp(conf.dest.sll_addr, from.sll_addr, 6))
					continue;
			
			if(ntohs(from.sll_protocol) == ETH_P_EGETTY) {
				if(conf.debug) printf("Received EGETTY\n");
				p = skb->data;
				if(*p == EGETTY_HELLO) {
					if(conf.scan) {
						p++;
						printf("Console: %d ", *p);
						for(i=0;i<6;i++)
							printf("%02x%s", from.sll_addr[i], i==5?"":":");
						printf("\n");
					}
					continue;
				}
				if(*p == EGETTY_OUT || *p == EGETTY_KMSG) {
					p++;
					if(*p++ != conf.console) continue;
					len = *p++ << 8;
					len += *p;
					skb_trim(skb, len);
					skb_pull(skb, 4);
					if(!conf.scan) write(1, skb->data, skb->len);
				}
				continue;
			}
		}
		
	}
	
	exit(0);
}
示例#2
0
文件: http.c 项目: sequenced/wsd
int
http_recv(sk_t *sk)
{
     AN(skb_rdsz(sk->recvbuf));

     if (!has_rnrn_termination(sk->recvbuf)) {
          wsd_errno = WSD_EINPUT;
          return (-1);
     }

     int rv;
     chunk_t tok;
     memset(&tok, 0, sizeof(chunk_t));
     rv = http_header_tok(&sk->recvbuf->data[sk->recvbuf->rdpos], &tok);
     if (0 > rv) {
          if (LOG_VVERBOSE <= wsd_cfg->verbose) {
               printf("\t%s: errno=%d\n", __func__, errno);
          }

          goto error;
     }

     http_req_t hreq;
     memset(&hreq, 0, sizeof(http_req_t));

     /* Parse status line, see whether or not it's a request ... */
     if (0 > parse_request_line(&tok, &hreq)) {

          if (LOG_VVERBOSE <= wsd_cfg->verbose) {
               printf("\t%s: errno=%d\n", __func__, errno);
          }

          if (0 == skb_put_str(sk->sendbuf, HTTP_400)) {
               sk->close_on_write = 1;
          }

          goto error;
     }

     /* ... validate request line ... */
     if (!is_valid_req_line(&hreq)) {

          if (0 == skb_put_str(sk->sendbuf, HTTP_400)) {
               sk->close_on_write = 1;
          }

          goto error;
     }

     /* ... tokenise and parse header fields ... */
     while (0 < http_header_tok(NULL, &tok)) {

          if (0 > parse_header_field(&tok, &hreq)) {
               
               if (LOG_VVERBOSE <= wsd_cfg->verbose) {
                    printf("\t%s: errno=%d\n", __func__, errno);
               }

               if (0 == skb_put_str(sk->sendbuf, HTTP_400)) {
                    sk->close_on_write = 1;
               }

               goto error;
          }
     }

     /* ... and finally, validate HTTP protocol fields. */
     if (!is_valid_host_header_field(&hreq)) {

          if (LOG_VVERBOSE <= wsd_cfg->verbose) {
               printf("\t%s: invalid host header field\n", __func__);
          }

          /*
           * Implementing as MUST; see RFC7230, section 5.4 and
           * RFC6455, section 4.1
           */
          if (0 == skb_put_str(sk->sendbuf, HTTP_400)) {
               sk->close_on_write = 1;
          }

          goto error;
     }

     if (!is_valid_upgrade_header_field(&hreq)) {

          if (LOG_VVERBOSE <= wsd_cfg->verbose) {
               printf("\t%s: invalid upgrade header field\n", __func__);
          }

          if (0 == skb_put_str(sk->sendbuf, HTTP_400)) {
               sk->close_on_write = 1;
          }

          goto error;
     }
     
     if (!is_valid_connection_header_field(&hreq)) {

          if (LOG_VVERBOSE <= wsd_cfg->verbose) {
               printf("\t%s: invalid connection header field\n", __func__);
          }

          if (0 == skb_put_str(sk->sendbuf, HTTP_400)) {
               sk->close_on_write = 1;
          }

          goto error;
     }

     skb_reset(sk->recvbuf);

     return sk->proto->decode_handshake(sk, &hreq);

error:
     skb_reset(sk->recvbuf);
     wsd_errno = WSD_EBADREQ;

     if (sk->close_on_write) {
          turn_off_events(sk, EPOLLIN);
          if (!(sk->events & EPOLLOUT)) {
               turn_on_events(sk, EPOLLOUT);
          }
     }

     return (-1);
}