00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "config.h"
00012
00013 #include <sys/types.h>
00014 #include <sys/time.h>
00015 #include <sys/ioctl.h>
00016
00017 #include <net/if.h>
00018 #include <net/pfilt.h>
00019
00020 #include <fcntl.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <unistd.h>
00024
00025 #include "dnet.h"
00026
00027 struct eth_handle {
00028 int fd;
00029 int sock;
00030 char device[16];
00031 };
00032
00033 eth_t *
00034 eth_open(const char *device)
00035 {
00036 struct eth_handle *e;
00037 int fd;
00038
00039 if ((e = calloc(1, sizeof(*e))) != NULL) {
00040 strlcpy(e->device, device, sizeof(e->device));
00041 if ((e->fd = pfopen(e->device, O_WRONLY)) < 0 ||
00042 (e->sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
00043 e = eth_close(e);
00044 }
00045 return (e);
00046 }
00047
00048 int
00049 eth_get(eth_t *e, eth_addr_t *ea)
00050 {
00051 struct ifdevea ifd;
00052
00053 strlcpy(ifd.ifr_name, e->device, sizeof(ifd.ifr_name));
00054 if (ioctl(e->sock, SIOCRPHYSADDR, &ifd) < 0)
00055 return (-1);
00056 memcpy(ea, ifd.current_pa, ETH_ADDR_LEN);
00057 return (0);
00058 }
00059
00060 int
00061 eth_set(eth_t *e, const eth_addr_t *ea)
00062 {
00063 struct ifdevea ifd;
00064
00065 strlcpy(ifd.ifr_name, e->device, sizeof(ifd.ifr_name));
00066 memcpy(ifd.current_pa, ea, ETH_ADDR_LEN);
00067 return (ioctl(e->sock, SIOCSPHYSADDR, &ifd));
00068 }
00069
00070 ssize_t
00071 eth_send(eth_t *e, const void *buf, size_t len)
00072 {
00073 return (write(e->fd, buf, len));
00074 }
00075
00076 eth_t *
00077 eth_close(eth_t *e)
00078 {
00079 if (e != NULL) {
00080 if (e->fd >= 0)
00081 close(e->fd);
00082 if (e->sock >= 0)
00083 close(e->sock);
00084 free(e);
00085 }
00086 return (NULL);
00087 }