|
|
|
@ -2508,72 +2508,226 @@ char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
|
|
|
|
|
return os;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__Darwin__)
|
|
|
|
|
#include <ifaddrs.h>
|
|
|
|
|
#include <net/if_dl.h>
|
|
|
|
|
|
|
|
|
|
void ast_set_default_eid(struct ast_eid *eid)
|
|
|
|
|
{
|
|
|
|
|
#if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_IFRU_IFRU_HWADDR)
|
|
|
|
|
int s, x = 0;
|
|
|
|
|
struct ifaddrs *ifap, *ifaphead;
|
|
|
|
|
int rtnerr;
|
|
|
|
|
const struct sockaddr_dl *sdl;
|
|
|
|
|
int alen;
|
|
|
|
|
caddr_t ap;
|
|
|
|
|
char eid_str[20];
|
|
|
|
|
struct ifreq ifr;
|
|
|
|
|
static const unsigned int MAXIF = 10;
|
|
|
|
|
unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
|
|
|
|
|
unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
|
|
|
|
|
|
|
|
|
s = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
|
if (s < 0) {
|
|
|
|
|
rtnerr = getifaddrs(&ifaphead);
|
|
|
|
|
if (rtnerr) {
|
|
|
|
|
ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (x = 0; x < MAXIF; x++) {
|
|
|
|
|
static const char *prefixes[] = { "eth", "em", "eno", "ens" };
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_LEN(prefixes); i++) {
|
|
|
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
|
|
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", prefixes[i], x);
|
|
|
|
|
if (!ioctl(s, SIOCGIFHWADDR, &ifr)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!ifaphead) {
|
|
|
|
|
ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
|
|
|
|
|
if (ifap->ifa_addr->sa_family != AF_LINK) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i == ARRAY_LEN(prefixes)) {
|
|
|
|
|
/* Try pciX#[1..N] */
|
|
|
|
|
for (i = 0; i < MAXIF; i++) {
|
|
|
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
|
|
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "pci%d#%u", x, i);
|
|
|
|
|
if (!ioctl(s, SIOCGIFHWADDR, &ifr)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (i == MAXIF) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
sdl = (const struct sockaddr_dl *) ifap->ifa_addr;
|
|
|
|
|
ap = ((caddr_t) ((sdl)->sdl_data + (sdl)->sdl_nlen));
|
|
|
|
|
alen = sdl->sdl_alen;
|
|
|
|
|
if (alen != 6 || !(memcmp(ap, &empty_mac, 6) && memcmp(ap, &full_mac, 6))) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(eid, ((unsigned char *)&ifr.ifr_hwaddr) + 2, sizeof(*eid));
|
|
|
|
|
ast_debug(1, "Seeding global EID '%s' from '%s' using 'siocgifhwaddr'\n", ast_eid_to_str(eid_str, sizeof(eid_str), eid), ifr.ifr_name);
|
|
|
|
|
memcpy(eid, ap, sizeof(*eid));
|
|
|
|
|
ast_debug(1, "Seeding global EID '%s'\n",
|
|
|
|
|
ast_eid_to_str(eid_str, sizeof(eid_str), eid));
|
|
|
|
|
freeifaddrs(ifaphead);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
freeifaddrs(ifaphead);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#elif defined(SOLARIS)
|
|
|
|
|
#include <sys/sockio.h>
|
|
|
|
|
#include <net/if_arp.h>
|
|
|
|
|
|
|
|
|
|
void ast_set_default_eid(struct ast_eid *eid)
|
|
|
|
|
{
|
|
|
|
|
int s;
|
|
|
|
|
int x;
|
|
|
|
|
int res = 0;
|
|
|
|
|
struct lifreq *ifr = NULL;
|
|
|
|
|
struct lifnum ifn;
|
|
|
|
|
struct lifconf ifc;
|
|
|
|
|
struct arpreq ar;
|
|
|
|
|
struct sockaddr_in *sa, *sa2;
|
|
|
|
|
char *buf = NULL;
|
|
|
|
|
char eid_str[20];
|
|
|
|
|
int bufsz;
|
|
|
|
|
unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
|
|
|
|
|
unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
|
|
|
|
|
|
|
|
|
s = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
|
if (s <= 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "Unable to open a socket for seeding global EID. "
|
|
|
|
|
" You will have to set it manually.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get a count of interfaces on the machine */
|
|
|
|
|
ifn.lifn_family = AF_UNSPEC;
|
|
|
|
|
ifn.lifn_flags = 0;
|
|
|
|
|
ifn.lifn_count = 0;
|
|
|
|
|
if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
|
|
|
|
|
" You will have to set it manually.\n");
|
|
|
|
|
close(s);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bufsz = ifn.lifn_count * sizeof(struct lifreq);
|
|
|
|
|
if (!(buf = ast_malloc(bufsz))) {
|
|
|
|
|
ast_log(LOG_WARNING, "Unable to allocate memory for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
close(s);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
memset(buf, 0, bufsz);
|
|
|
|
|
|
|
|
|
|
/* Get a list of interfaces on the machine */
|
|
|
|
|
ifc.lifc_len = bufsz;
|
|
|
|
|
ifc.lifc_buf = buf;
|
|
|
|
|
ifc.lifc_family = AF_UNSPEC;
|
|
|
|
|
ifc.lifc_flags = 0;
|
|
|
|
|
if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
ast_free(buf);
|
|
|
|
|
close(s);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (ifr = (struct lifreq *)buf, x = 0; x < ifn.lifn_count; ifr++, x++) {
|
|
|
|
|
unsigned char *p;
|
|
|
|
|
|
|
|
|
|
sa = (struct sockaddr_in *)&(ifr->lifr_addr);
|
|
|
|
|
sa2 = (struct sockaddr_in *)&(ar.arp_pa);
|
|
|
|
|
*sa2 = *sa;
|
|
|
|
|
|
|
|
|
|
if(ioctl(s, SIOCGARP, &ar) >= 0) {
|
|
|
|
|
p = (unsigned char *)&(ar.arp_ha.sa_data);
|
|
|
|
|
if (!(memcmp(p, &empty_mac, 6) && memcmp(p, &full_mac, 6))) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(eid, p, sizeof(*eid));
|
|
|
|
|
ast_debug(1, "Seeding global EID '%s'\n",
|
|
|
|
|
ast_eid_to_str(eid_str, sizeof(eid_str), eid));
|
|
|
|
|
ast_free(buf);
|
|
|
|
|
close(s);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
ast_free(buf);
|
|
|
|
|
close(s);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
#if defined(ifa_broadaddr) && !defined(SOLARIS)
|
|
|
|
|
void ast_set_default_eid(struct ast_eid *eid)
|
|
|
|
|
{
|
|
|
|
|
int s;
|
|
|
|
|
int i;
|
|
|
|
|
struct ifreq *ifr;
|
|
|
|
|
struct ifreq *ifrp;
|
|
|
|
|
struct ifconf ifc;
|
|
|
|
|
char *buf = NULL;
|
|
|
|
|
char eid_str[20];
|
|
|
|
|
struct ifaddrs *ifap;
|
|
|
|
|
|
|
|
|
|
if (getifaddrs(&ifap) == 0) {
|
|
|
|
|
struct ifaddrs *p;
|
|
|
|
|
for (p = ifap; p; p = p->ifa_next) {
|
|
|
|
|
if ((p->ifa_addr->sa_family == AF_LINK) && !(p->ifa_flags & IFF_LOOPBACK) && (p->ifa_flags & IFF_RUNNING)) {
|
|
|
|
|
struct sockaddr_dl* sdp = (struct sockaddr_dl*) p->ifa_addr;
|
|
|
|
|
memcpy(&(eid->eid), sdp->sdl_data + sdp->sdl_nlen, 6);
|
|
|
|
|
ast_debug(1, "Seeding global EID '%s' from '%s' using 'getifaddrs'\n", ast_eid_to_str(eid_str, sizeof(eid_str), eid), p->ifa_name);
|
|
|
|
|
freeifaddrs(ifap);
|
|
|
|
|
return;
|
|
|
|
|
int bufsz, num_interfaces;
|
|
|
|
|
unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
|
|
|
|
|
unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
|
|
|
|
|
|
|
|
|
s = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
|
if (s <= 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "Unable to open socket for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ifc.ifc_len = 0;
|
|
|
|
|
ifc.ifc_buf = NULL;
|
|
|
|
|
if (ioctl(s, SIOCGIFCONF, &ifc) || ifc.ifc_len <= 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
close(s);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
bufsz = ifc.ifc_len;
|
|
|
|
|
|
|
|
|
|
if (!(buf = ast_malloc(bufsz))) {
|
|
|
|
|
ast_log(LOG_WARNING, "Unable to allocate memory for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
close(s);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ifc.ifc_buf = buf;
|
|
|
|
|
if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "Unable to retrieve ethernet interfaces for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
ast_free(buf);
|
|
|
|
|
close(s);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ifrp = ifc.ifc_req;
|
|
|
|
|
num_interfaces = ifc.ifc_len / sizeof(*ifr);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < num_interfaces; i++) {
|
|
|
|
|
ifr = &ifrp[i];
|
|
|
|
|
if (!ioctl(s, SIOCGIFHWADDR, ifr)) {
|
|
|
|
|
unsigned char *hwaddr = (unsigned char *) ifr->ifr_hwaddr.sa_data;
|
|
|
|
|
|
|
|
|
|
if (!(memcmp(hwaddr, &empty_mac, 6) && memcmp(hwaddr, &full_mac, 6))) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(eid, hwaddr, sizeof(*eid));
|
|
|
|
|
ast_debug(1, "Seeding global EID '%s' from '%s' using 'siocgifhwaddr'\n",
|
|
|
|
|
ast_eid_to_str(eid_str, sizeof(eid_str), eid), ifr->ifr_name);
|
|
|
|
|
ast_free(buf);
|
|
|
|
|
close(s);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
freeifaddrs(ifap);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. You will have to set it manually.\n");
|
|
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "No ethernet interface found for seeding global EID. "
|
|
|
|
|
"You will have to set it manually.\n");
|
|
|
|
|
ast_free(buf);
|
|
|
|
|
close(s);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif /* LINUX */
|
|
|
|
|
|
|
|
|
|
int ast_str_to_eid(struct ast_eid *eid, const char *s)
|
|
|
|
|
{
|
|
|
|
|