version 1.1, 2012/02/21 22:14:23
|
version 1.1.1.2, 2013/07/22 11:54:42
|
Line 8
|
Line 8
|
* All rights reserved. |
* All rights reserved. |
* |
* |
* Copyright (c) 1993, 1994, 1995, 1996, 1997 |
* Copyright (c) 1993, 1994, 1995, 1996, 1997 |
* The Regents of the University of California. All rights reserved. | * The Regents of the University of California. All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that: (1) source code distributions |
* modification, are permitted provided that: (1) source code distributions |
Line 29
|
Line 29
|
|
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/file.h> |
#include <sys/file.h> |
|
#include <netinet/in.h> |
|
#include <netinet/udp.h> |
|
#include <netinet/tcp.h> |
|
|
#if (HAVE_CONFIG_H) |
#if (HAVE_CONFIG_H) |
#include "../include/config.h" |
#include "../include/config.h" |
Line 50
|
Line 53
|
#endif |
#endif |
|
|
|
|
struct libnet_link_int * | /** |
libnet_open_link_interface(int8_t *device, int8_t *ebuf) | * |
| */ |
| int |
| libnet_open_link(libnet_t *l) |
{ |
{ |
int fd; |
int fd; |
struct sockaddr_raw sr; |
struct sockaddr_raw sr; |
u_int v; | uint v; |
struct libnet_link_int *l; | |
|
|
l = (struct libnet_link_int *)malloc(sizeof(*l)); | if (l == NULL) { |
if (l == NULL) | return -1; |
{ | |
sprintf(ebuf, "malloc: %s", strerror(errno)); | |
return (NULL); | |
} |
} |
memset(l, 0, sizeof(*l)); | |
l->fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN); |
l->fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN); |
if (l->fd < 0) | |
{ | if (l->fd < 0) { |
sprintf(ebuf, "drain socket: %s", strerror(errno)); | sprintf(l->err_buf, "drain socket: %s", strerror(errno)); |
goto bad; |
goto bad; |
} |
} |
|
|
memset(&sr, 0, sizeof(sr)); |
memset(&sr, 0, sizeof(sr)); |
sr.sr_family = AF_RAW; |
sr.sr_family = AF_RAW; |
strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname) - 1); | strncpy(sr.sr_ifname, l->device, sizeof(sr.sr_ifname) - 1); |
sr.sr_name[sizeof(sr.sr_name) - 1] = '\0'; | sr.sr_ifname[sizeof(sr.sr_ifname) - 1] = '\0'; |
|
|
if (bind(l->fd, (struct sockaddr *)&sr, sizeof(sr))) | if (bind(l->fd, (struct sockaddr *)&sr, sizeof(sr))) { |
{ | sprintf(l->err_buf, "drain bind: %s", strerror(errno)); |
sprintf(ebuf, "drain bind: %s", strerror(errno)); | |
goto bad; |
goto bad; |
} |
} |
|
|
/* |
/* |
* XXX hack - map device name to link layer type |
* XXX hack - map device name to link layer type |
*/ |
*/ |
if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */ | if (strncmp("et", l->device, 2) == 0 || /* Challenge 10 Mbit */ |
strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit, O2 10/100 */ | strncmp("ec", l->device, 2) == 0 || /* Indigo/Indy 10 Mbit, O2 10/100 */ |
strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */ | strncmp("ef", l->device, 2) == 0 || /* O200/2000 10/100 Mbit */ |
strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */ | strncmp("gfe", l->device, 3) == 0 || /* GIO 100 Mbit */ |
strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */ | strncmp("fxp", l->device, 3) == 0 || /* Challenge VME Enet */ |
strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */ | strncmp("ep", l->device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */ |
strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */ | strncmp("vfe", l->device, 3) == 0 || /* Challenge VME 100Mbit */ |
strncmp("fa", device, 2) == 0 || | strncmp("fa", l->device, 2) == 0 || |
strncmp("qaa", device, 3) == 0) | strncmp("qaa", l->device, 3) == 0) { |
{ | l->link_type = DLT_EN10MB; |
l->linktype = DLT_EN10MB; | |
} |
} |
else if (strncmp("ipg", device, 3) == 0 || | else if (strncmp("ipg", l->device, 3) == 0 || |
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */ | strncmp("rns", l->device, 3) == 0 || /* O2/200/2000 FDDI */ |
strncmp("xpi", device, 3) == 0) | strncmp("xpi", l->device, 3) == 0) { |
{ | l->link_type = DLT_FDDI; |
l->linktype = DLT_FDDI; | } |
} | else if (strncmp("ppp", l->device, 3) == 0) { |
else if (strncmp("ppp", device, 3) == 0) { | l->link_type = DLT_RAW; |
l->linktype = DLT_RAW; | } else if (strncmp("lo", l->device, 2) == 0) { |
} else if (strncmp("lo", device, 2) == 0) { | l->link_type = DLT_NULL; |
l->linktype = DLT_NULL; | } else { |
} else { | sprintf(l->err_buf, "drain: unknown physical layer type"); |
sprintf(ebuf, "drain: unknown physical layer type"); | goto bad; |
goto bad; | } |
} | |
|
|
return (l); | return 1; |
bad: | bad: |
close(fd); | close(fd); |
free(l); | free(l); |
return (NULL); | return -1; |
} |
} |
|
|
|
|
int |
int |
libnet_close_link_interface(struct libnet_link_int *l) | libnet_close_link(libnet_t *l) |
{ |
{ |
if (close(l->fd) == 0) |
if (close(l->fd) == 0) |
{ |
{ |
free(l); |
|
return (1); |
return (1); |
} |
} |
else |
else |
{ |
{ |
free(l); |
|
return (-1); |
return (-1); |
} |
} |
} |
} |
|
|
|
|
int |
int |
libnet_write_link_layer(struct libnet_link_int *l, const int8_t *device, | libnet_write_link(libnet_t *l, const uint8_t *buf, uint32_t len) |
u_int8_t *buf, int len) | |
{ |
{ |
int c; |
int c; |
struct ifreq ifr; |
struct ifreq ifr; |
struct ether_header *eh = (struct ether_header *)buf; |
struct ether_header *eh = (struct ether_header *)buf; |
| |
memset(&ifr, 0, sizeof(ifr)); |
memset(&ifr, 0, sizeof(ifr)); |
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); | strncpy(ifr.ifr_name, l->device, sizeof(ifr.ifr_name)); |
| |
if (ioctl(l->fd, SIOCGIFADDR, &ifr) == -1) |
if (ioctl(l->fd, SIOCGIFADDR, &ifr) == -1) |
{ |
{ |
perror("ioctl SIOCGIFADDR"); |
perror("ioctl SIOCGIFADDR"); |
return (-1); |
return (-1); |
} |
} |
| |
memcpy(eh->ether_shost, ifr.ifr_addr.sa_data, sizeof(eh->ether_shost)); |
memcpy(eh->ether_shost, ifr.ifr_addr.sa_data, sizeof(eh->ether_shost)); |
| |
if (write(l->fd, buf, len) == -1) |
if (write(l->fd, buf, len) == -1) |
{ |
{ |
/* err */ |
/* err */ |
Line 164 libnet_write_link_layer(struct libnet_link_int *l, con
|
Line 160 libnet_write_link_layer(struct libnet_link_int *l, con
|
|
|
return (len); |
return (len); |
} |
} |
|
|
|
struct libnet_ether_addr * |
|
libnet_get_hwaddr(libnet_t *l) |
|
{ |
|
struct ifreq ifdat; |
|
int s = -1; |
|
struct libnet_ether_addr *ea = NULL; |
|
|
|
if (-1 == (s = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP))) { |
|
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
|
"socket(): %s", strerror(errno)); |
|
goto errout; |
|
} |
|
memset(&ifdat, 0, sizeof(struct ifreq)); |
|
strncpy(ifdat.ifr_name, l->device, IFNAMSIZ); |
|
if (ioctl(s, SIOCGIFADDR, &ifdat)) { |
|
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
|
"SIOCGIFADDR: %s", strerror(errno)); |
|
goto errout; |
|
} |
|
if (!(ea = malloc(sizeof(struct libnet_ether_addr)))) { |
|
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
|
"malloc(): %s", strerror(errno)); |
|
goto errout; |
|
} |
|
memcpy(ea, &ifdat.ifr_addr.sa_data, ETHER_ADDR_LEN); |
|
close(s); |
|
s = -1; |
|
return ea; |
|
|
|
errout: |
|
if (s > 0) { |
|
close(s); |
|
} |
|
if (ea) { |
|
free(ea); |
|
ea = 0; |
|
} |
|
return 0; |
|
} |
|
/* ---- Emacs Variables ---- |
|
* Local Variables: |
|
* c-basic-offset: 4 |
|
* indent-tabs-mode: nil |
|
* End: |
|
*/ |