8 #define MIN(a, b) ((a) < (b) ? (a) : (b))
14 struct timeval timeout;
18 struct ethsock *ethsock_create(const char *interface, uint16_t protocol)
20 char buf[PCAP_ERRBUF_SIZE];
21 struct bpf_program fp;
25 sock = malloc(sizeof(struct ethsock));
33 sock->pcap = pcap_open_live(interface, BUFSIZ, 1, 1, buf);
35 fprintf(stderr, "pcap_open_live: %s\n", buf);
40 fprintf(stderr, "Warning: %s.\n", buf);
43 if (pcap_datalink(sock->pcap) != DLT_EN10MB) {
44 fprintf(stderr, "Interface %s not supported.\n", interface);
48 sock->fd = pcap_get_selectable_fd(sock->pcap);
50 fprintf(stderr, "No selectable file descriptor available.\n");
54 snprintf(buf, sizeof(buf), "ether proto %04x", protocol);
55 err = pcap_compile(sock->pcap, &fp, buf, 0, PCAP_NETMASK_UNKNOWN);
57 pcap_perror(sock->pcap, "pcap_compile");
61 if ((err = pcap_setfilter(sock->pcap, &fp))) {
62 pcap_perror(sock->pcap, "pcap_setfilter");
69 pcap_close(sock->pcap);
75 ssize_t ethsock_recv(struct ethsock *sock, void *buf, size_t len)
77 struct pcap_pkthdr* hdr;
82 if (sock->timeout.tv_sec || sock->timeout.tv_usec) {
84 FD_SET(sock->fd, &fds);
86 status = select(sock->fd + 1, &fds, NULL, NULL, &sock->timeout);
90 } else if (status == 0) {
95 status = pcap_next_ex(sock->pcap, &hdr, &capbuf);
98 memcpy(buf, capbuf, MIN(len, hdr->caplen));
103 pcap_perror(sock->pcap, "pcap_next_ex");
106 fprintf(stderr, "pcap_next_ex: returned %d.\n", status);
111 int ethsock_send(struct ethsock *sock, void *buf, size_t len)
113 #if defined(_WIN32) || defined(_WIN64)
114 if (pcap_sendpacket(sock->pcap, buf, len) == 0) {
117 pcap_perror(sock->pcap, "pcap_sendpacket");
121 if (pcap_inject(sock->pcap, buf, len) == len) {
124 pcap_perror(sock->pcap, "pcap_inject");
130 int ethsock_close(struct ethsock *sock)
132 pcap_close(sock->pcap);
137 int ethsock_set_timeout(struct ethsock *sock, unsigned msec)
139 sock->timeout.tv_sec = msec / 1000;
140 sock->timeout.tv_usec = (msec % 1000) * 1000;