Some rawsock changes
This commit is contained in:
parent
3b1cdc7931
commit
1d53062f66
2 changed files with 33 additions and 34 deletions
63
rawsock.c
63
rawsock.c
|
|
@ -3,6 +3,10 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
struct rawsock
|
struct rawsock
|
||||||
{
|
{
|
||||||
pcap_t *pcap;
|
pcap_t *pcap;
|
||||||
|
|
@ -10,9 +14,9 @@ struct rawsock
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rawsock *rawsock_create(const char *interface)
|
struct rawsock *rawsock_create(const char *interface, uint16_t protocol)
|
||||||
{
|
{
|
||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
char buf[PCAP_ERRBUF_SIZE];
|
||||||
struct bpf_program fp;
|
struct bpf_program fp;
|
||||||
struct rawsock *sock;
|
struct rawsock *sock;
|
||||||
int err;
|
int err;
|
||||||
|
|
@ -23,16 +27,16 @@ struct rawsock *rawsock_create(const char *interface)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
errbuf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|
||||||
sock->pcap = pcap_open_live(interface, BUFSIZ, 1, 1, errbuf);
|
sock->pcap = pcap_open_live(interface, BUFSIZ, 1, 1, buf);
|
||||||
if (!sock->pcap) {
|
if (!sock->pcap) {
|
||||||
fprintf(stderr, "pcap_open_live: %s\n", errbuf);
|
fprintf(stderr, "pcap_open_live: %s\n", buf);
|
||||||
goto cleanup_malloc;
|
goto cleanup_malloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*errbuf) {
|
if (*buf) {
|
||||||
fprintf(stderr, "Warning: %s.\n", errbuf);
|
fprintf(stderr, "Warning: %s.\n", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcap_datalink(sock->pcap) != DLT_EN10MB) {
|
if (pcap_datalink(sock->pcap) != DLT_EN10MB) {
|
||||||
|
|
@ -40,8 +44,14 @@ struct rawsock *rawsock_create(const char *interface)
|
||||||
goto cleanup_pcap;
|
goto cleanup_pcap;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pcap_compile(sock->pcap, &fp, "ether proto 0x0912", 0,
|
sock->fd = pcap_get_selectable_fd(sock->pcap);
|
||||||
PCAP_NETMASK_UNKNOWN);
|
if (sock->fd == -1) {
|
||||||
|
fprintf(stderr, "No selectable file descriptor available.\n");
|
||||||
|
goto cleanup_pcap;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "ether proto %04x", protocol);
|
||||||
|
err = pcap_compile(sock->pcap, &fp, buf, 0, PCAP_NETMASK_UNKNOWN);
|
||||||
if (err) {
|
if (err) {
|
||||||
pcap_perror(sock->pcap, "pcap_compile");
|
pcap_perror(sock->pcap, "pcap_compile");
|
||||||
goto cleanup_pcap;
|
goto cleanup_pcap;
|
||||||
|
|
@ -52,12 +62,6 @@ struct rawsock *rawsock_create(const char *interface)
|
||||||
goto cleanup_pcap;
|
goto cleanup_pcap;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock->fd = pcap_get_selectable_fd(sock->pcap);
|
|
||||||
if (sock->fd == -1) {
|
|
||||||
fprintf(stderr, "No selectable file descriptor available.\n");
|
|
||||||
goto cleanup_pcap;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sock;
|
return sock;
|
||||||
|
|
||||||
cleanup_pcap:
|
cleanup_pcap:
|
||||||
|
|
@ -67,9 +71,10 @@ cleanup_malloc:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rawsock_recv(struct rawsock *sock, uint8_t **buffer, unsigned *size)
|
ssize_t rawsock_recv(struct rawsock *sock, uint8_t *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct pcap_pkthdr* hdr;
|
struct pcap_pkthdr* hdr;
|
||||||
|
const u_char *capbuf;
|
||||||
int status;
|
int status;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
|
|
||||||
|
|
@ -86,39 +91,33 @@ int rawsock_recv(struct rawsock *sock, uint8_t **buffer, unsigned *size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = pcap_next_ex(sock->pcap, &hdr, (const u_char**)buffer);
|
status = pcap_next_ex(sock->pcap, &hdr, &capbuf);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 1:
|
case 1:
|
||||||
status = 0;
|
memcpy(buf, capbuf, MIN(len, hdr->caplen));
|
||||||
*size = hdr->caplen;
|
return hdr->caplen;
|
||||||
break;
|
|
||||||
case 0:
|
case 0:
|
||||||
status = 1;
|
return 0;
|
||||||
break;
|
|
||||||
case -1:
|
case -1:
|
||||||
pcap_perror(sock->pcap, "pcap_next_ex");
|
pcap_perror(sock->pcap, "pcap_next_ex");
|
||||||
status = -1;
|
return -1;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "pcap_next_ex: returned %d.\n", status);
|
fprintf(stderr, "pcap_next_ex: returned %d.\n", status);
|
||||||
status = -1;
|
return -1;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
int rawsock_send(struct rawsock *sock, uint8_t *buf, size_t len)
|
||||||
}
|
|
||||||
|
|
||||||
int rawsock_send(struct rawsock *sock, uint8_t *buffer, size_t size)
|
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
if (pcap_sendpacket(sock->pcap, buffer, size) == 0) {
|
if (pcap_sendpacket(sock->pcap, buf, len) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
pcap_perror(sock->pcap, "pcap_sendpacket");
|
pcap_perror(sock->pcap, "pcap_sendpacket");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (pcap_inject(sock->pcap, buffer, size) != size) {
|
if (pcap_inject(sock->pcap, buf, len) == len) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
pcap_perror(sock->pcap, "pcap_inject");
|
pcap_perror(sock->pcap, "pcap_inject");
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
struct rawsock;
|
struct rawsock;
|
||||||
|
|
||||||
struct rawsock *rawsock_create(const char *interface);
|
struct rawsock *rawsock_create(const char *interface, uint16_t protocol);
|
||||||
int rawsock_close(struct rawsock *sock);
|
int rawsock_close(struct rawsock *sock);
|
||||||
int rawsock_send(struct rawsock *sock, uint8_t *buffer, size_t size);
|
int rawsock_send(struct rawsock *sock, uint8_t *buf, size_t len);
|
||||||
int rawsock_recv(struct rawsock *sock, uint8_t **buffer, unsigned *size);
|
ssize_t rawsock_recv(struct rawsock *sock, uint8_t *buf, size_t len);
|
||||||
int rawsock_set_timeout(struct rawsock *sock, unsigned msec);
|
int rawsock_set_timeout(struct rawsock *sock, unsigned msec);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue