Annotation of embedaddon/libnet/src/libnet_link_dlpi.c, revision 1.1
1.1 ! misho 1: /*
! 2: * $Id: libnet_link_dlpi.c,v 1.8 2004/01/28 19:45:00 mike Exp $
! 3: *
! 4: * libnet
! 5: * libnet_dlpi.c - dlpi routines
! 6: *
! 7: * Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
! 8: * All rights reserved.
! 9: *
! 10: * Copyright (c) 1993, 1994, 1995, 1996, 1997
! 11: * The Regents of the University of California. All rights reserved.
! 12: *
! 13: * Redistribution and use in source and binary forms, with or without
! 14: * modification, are permitted provided that: (1) source code distributions
! 15: * retain the above copyright notice and this paragraph in its entirety, (2)
! 16: * distributions including binary code include the above copyright notice and
! 17: * this paragraph in its entirety in the documentation or other materials
! 18: * provided with the distribution, and (3) all advertising materials mentioning
! 19: * features or use of this software display the following acknowledgement:
! 20: * ``This product includes software developed by the University of California,
! 21: * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
! 22: * the University nor the names of its contributors may be used to endorse
! 23: * or promote products derived from this software without specific prior
! 24: * written permission.
! 25: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
! 26: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
! 27: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
! 28: *
! 29: * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk),
! 30: * University College London.
! 31: */
! 32:
! 33:
! 34: #if (HAVE_CONFIG_H)
! 35: #include "../include/config.h"
! 36: #endif
! 37: #include <sys/types.h>
! 38: #include <sys/time.h>
! 39: #ifdef HAVE_SYS_BUFMOD_H
! 40: #include <sys/bufmod.h>
! 41: #endif
! 42: #include <sys/dlpi.h>
! 43: #ifdef HAVE_HPUX9
! 44: #include <sys/socket.h>
! 45: #endif
! 46: #ifdef DL_HP_PPA_ACK_OBS
! 47: #include <sys/stat.h>
! 48: #endif
! 49: #include <sys/stream.h>
! 50: #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
! 51: #include <sys/systeminfo.h>
! 52: #endif
! 53:
! 54: #ifdef HAVE_SYS_DLPI_EXT_H
! 55: #include <sys/dlpi_ext.h>
! 56: #endif
! 57:
! 58: #ifdef HAVE_HPUX9
! 59: #include <net/if.h>
! 60: #endif
! 61:
! 62: #include <ctype.h>
! 63: #ifdef HAVE_HPUX9
! 64: #include <nlist.h>
! 65: #include <dlpi_ext.h>
! 66: #endif
! 67: #include <errno.h>
! 68: #include <fcntl.h>
! 69: #include <memory.h>
! 70: #include <stdio.h>
! 71: #include <stdlib.h>
! 72: #include <string.h>
! 73: #include <stropts.h>
! 74: #include <unistd.h>
! 75:
! 76: #include "../include/libnet.h"
! 77: #include "../include/bpf.h"
! 78:
! 79: #include "../include/gnuc.h"
! 80: #ifdef HAVE_OS_PROTO_H
! 81: #include "../include/os-proto.h"
! 82: #endif
! 83:
! 84: #ifndef DLPI_DEV_PREFIX
! 85: #define DLPI_DEV_PREFIX "/dev"
! 86: #endif
! 87:
! 88: #define MAXDLBUF 8192
! 89:
! 90: /* Forwards */
! 91: static int dlattachreq(int, bpf_u_int32, int8_t *);
! 92: static int dlbindack(int, int8_t *, int8_t *);
! 93: static int dlbindreq(int, bpf_u_int32, int8_t *);
! 94: static int dlinfoack(int, int8_t *, int8_t *);
! 95: static int dlinforeq(int, int8_t *);
! 96: static int dlokack(int, const int8_t *, int8_t *, int8_t *);
! 97: static int recv_ack(int, int, const int8_t *, int8_t *, int8_t *);
! 98: static int send_request(int, int8_t *, int, int8_t *, int8_t *, int);
! 99: #ifdef HAVE_SYS_BUFMOD_H
! 100: static int strioctl(int, int, int, int8_t *);
! 101: #endif
! 102: #ifdef HAVE_HPUX9
! 103: static int dlpi_kread(int, off_t, void *, u_int, int8_t *);
! 104: #endif
! 105: #ifdef HAVE_DEV_DLPI
! 106: static int get_dlpi_ppa(int, const int8_t *, int, int8_t *);
! 107: #endif
! 108:
! 109: /* XXX Needed by HP-UX (at least) */
! 110: static bpf_u_int32 ctlbuf[MAXDLBUF];
! 111:
! 112:
! 113: int
! 114: libnet_open_link(libnet_t *l)
! 115: {
! 116: register int8_t *cp;
! 117: int8_t *eos;
! 118: register int ppa;
! 119: register dl_info_ack_t *infop;
! 120: bpf_u_int32 buf[MAXDLBUF];
! 121: int8_t dname[100];
! 122: #ifndef HAVE_DEV_DLPI
! 123: int8_t dname2[100];
! 124: #endif
! 125:
! 126: if (l == NULL)
! 127: {
! 128: return (-1);
! 129: }
! 130:
! 131: /*
! 132: * Determine device and ppa
! 133: */
! 134: cp = strpbrk(l->device, "0123456789");
! 135: if (cp == NULL)
! 136: {
! 137: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
! 138: "%s(): %s is missing unit number\n", __func__, l->device);
! 139: goto bad;
! 140: }
! 141: ppa = strtol(cp, &eos, 10);
! 142: if (*eos != '\0')
! 143: {
! 144: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
! 145: "%s(): %s bad unit number\n", __func__, l->device);
! 146: goto bad;
! 147: }
! 148:
! 149: if (*(l->device) == '/')
! 150: {
! 151: memset(&dname, 0, sizeof(dname));
! 152: strncpy(dname, l->device, sizeof(dname) - 1);
! 153: dname[sizeof(dname) - 1] = '\0';
! 154: }
! 155: else
! 156: {
! 157: sprintf(dname, "%s/%s", DLPI_DEV_PREFIX, l->device);
! 158: }
! 159: #ifdef HAVE_DEV_DLPI
! 160: /*
! 161: * Map network device to /dev/dlpi unit
! 162: */
! 163: cp = "/dev/dlpi";
! 164:
! 165: l->fd = open(cp, O_RDWR);
! 166: if (l->fd == -1)
! 167: {
! 168: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): open(): %s: %s\n",
! 169: __func__, cp, strerror(errno));
! 170: goto bad;
! 171: }
! 172:
! 173: /*
! 174: * Map network interface to /dev/dlpi unit
! 175: */
! 176: ppa = get_dlpi_ppa(l->fd, dname, ppa, l->err_buf);
! 177: if (ppa < 0)
! 178: {
! 179: goto bad;
! 180: }
! 181: #else
! 182: /*
! 183: * Try device without unit number
! 184: */
! 185: strcpy(dname2, dname);
! 186: cp = strchr(dname, *cp);
! 187: *cp = '\0';
! 188:
! 189: l->fd = open(dname, O_RDWR);
! 190: if (l->fd == -1)
! 191: {
! 192: if (errno != ENOENT)
! 193: {
! 194: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): open(): %s: %s\n",
! 195: __func__, dname, strerror(errno));
! 196: goto bad;
! 197: }
! 198:
! 199: /*
! 200: * Try again with unit number
! 201: */
! 202: l->fd = open(dname2, O_RDWR);
! 203: if (l->fd == -1)
! 204: {
! 205: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): open(): %s: %s\n",
! 206: __func__, dname2, strerror(errno));
! 207: goto bad;
! 208: }
! 209:
! 210: cp = dname2;
! 211: while (*cp && !isdigit((int)*cp))
! 212: {
! 213: cp++;
! 214: }
! 215: if (*cp)
! 216: {
! 217: ppa = atoi(cp);
! 218: }
! 219: else
! 220: /*
! 221: * XXX Assume unit zero
! 222: */
! 223: ppa = 0;
! 224: }
! 225: #endif
! 226: /*
! 227: * Attach if "style 2" provider
! 228: */
! 229: if (dlinforeq(l->fd, l->err_buf) < 0 ||
! 230: dlinfoack(l->fd, (int8_t *)buf, l->err_buf) < 0)
! 231: {
! 232: goto bad;
! 233: }
! 234: infop = &((union DL_primitives *)buf)->info_ack;
! 235: if (infop->dl_provider_style == DL_STYLE2 &&
! 236: (dlattachreq(l->fd, ppa, l->err_buf)
! 237: < 0 || dlokack(l->fd, "attach", (int8_t *)buf, l->err_buf) < 0))
! 238: {
! 239: goto bad;
! 240: }
! 241:
! 242: /*
! 243: * Bind HP-UX 9 and HP-UX 10.20
! 244: */
! 245: #if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20) || defined(HAVE_HPUX11) || defined(HAVE_SOLARIS)
! 246: if (dlbindreq(l->fd, 0, l->err_buf) < 0 ||
! 247: dlbindack(l->fd, (int8_t *)buf, l->err_buf) < 0)
! 248: {
! 249: goto bad;
! 250: }
! 251: #endif
! 252:
! 253: /*
! 254: * Determine link type
! 255: */
! 256: if (dlinforeq(l->fd, l->err_buf) < 0 ||
! 257: dlinfoack(l->fd, (int8_t *)buf, l->err_buf) < 0)
! 258: {
! 259: goto bad;
! 260: }
! 261:
! 262: infop = &((union DL_primitives *)buf)->info_ack;
! 263: switch (infop->dl_mac_type)
! 264: {
! 265: case DL_CSMACD:
! 266: case DL_ETHER:
! 267: l->link_type = DLT_EN10MB;
! 268: l->link_offset = 0xe;
! 269: break;
! 270: case DL_FDDI:
! 271: l->link_type = DLT_FDDI;
! 272: l->link_offset = 0x15;
! 273: break;
! 274: case DL_TPR:
! 275: l->link_type = DLT_PRONET;
! 276: l->link_offset = 0x16;
! 277: break;
! 278: default:
! 279: sprintf(l->err_buf, "%s(): unknown mac type 0x%lu\n", __func__,
! 280: (u_int32_t) infop->dl_mac_type);
! 281: goto bad;
! 282: }
! 283:
! 284: #ifdef DLIOCRAW
! 285: /*
! 286: * This is a non standard SunOS hack to get the ethernet header.
! 287: */
! 288: if (strioctl(l->fd, DLIOCRAW, 0, NULL) < 0)
! 289: {
! 290: sprintf(l->err_buf, "%s(): DLIOCRAW: %s\n", __func__, strerror(errno));
! 291: goto bad;
! 292: }
! 293: #endif
! 294:
! 295: return (1);
! 296: bad:
! 297: if (l->fd > 0)
! 298: {
! 299: close(l->fd); /* this can fail ok */
! 300: }
! 301: return (-1);
! 302: }
! 303:
! 304:
! 305: static int
! 306: send_request(int fd, int8_t *ptr, int len, int8_t *what, int8_t *ebuf,
! 307: int flags)
! 308: {
! 309: struct strbuf ctl;
! 310:
! 311: ctl.maxlen = 0;
! 312: ctl.len = len;
! 313: ctl.buf = ptr;
! 314:
! 315: if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0)
! 316: {
! 317: sprintf(ebuf, "%s(): putmsg \"%s\": %s\n", __func__, what,
! 318: strerror(errno));
! 319: return (-1);
! 320: }
! 321: return (0);
! 322: }
! 323:
! 324: static int
! 325: recv_ack(int fd, int size, const int8_t *what, int8_t *bufp, int8_t *ebuf)
! 326: {
! 327: union DL_primitives *dlp;
! 328: struct strbuf ctl;
! 329: int flags;
! 330:
! 331: ctl.maxlen = MAXDLBUF;
! 332: ctl.len = 0;
! 333: ctl.buf = bufp;
! 334:
! 335: flags = 0;
! 336: if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0)
! 337: {
! 338: sprintf(ebuf, "%s(): %s getmsg: %s\n", __func__, what, strerror(errno));
! 339: return (-1);
! 340: }
! 341:
! 342: dlp = (union DL_primitives *)ctl.buf;
! 343: switch (dlp->dl_primitive)
! 344: {
! 345: case DL_INFO_ACK:
! 346: case DL_PHYS_ADDR_ACK:
! 347: case DL_BIND_ACK:
! 348: case DL_OK_ACK:
! 349: #ifdef DL_HP_PPA_ACK
! 350: case DL_HP_PPA_ACK:
! 351: #endif
! 352: /*
! 353: * These are OK
! 354: */
! 355: break;
! 356:
! 357: case DL_ERROR_ACK:
! 358: switch (dlp->error_ack.dl_errno)
! 359: {
! 360: case DL_BADPPA:
! 361: sprintf(ebuf, "recv_ack: %s bad ppa (device unit)", what);
! 362: break;
! 363: case DL_SYSERR:
! 364: sprintf(ebuf, "recv_ack: %s: %s",
! 365: what, strerror(dlp->error_ack.dl_unix_errno));
! 366: break;
! 367: case DL_UNSUPPORTED:
! 368: sprintf(ebuf,
! 369: "recv_ack: %s: Service not supplied by provider", what);
! 370: break;
! 371: default:
! 372: sprintf(ebuf, "recv_ack: %s error 0x%x", what,
! 373: (bpf_u_int32)dlp->error_ack.dl_errno);
! 374: break;
! 375: }
! 376: return (-1);
! 377:
! 378: default:
! 379: sprintf(ebuf, "recv_ack: %s unexpected primitive ack 0x%x ",
! 380: what, (bpf_u_int32)dlp->dl_primitive);
! 381: return (-1);
! 382: }
! 383:
! 384: if (ctl.len < size)
! 385: {
! 386: sprintf(ebuf, "recv_ack: %s ack too small (%d < %d)",
! 387: what, ctl.len, size);
! 388: return (-1);
! 389: }
! 390: return (ctl.len);
! 391: }
! 392:
! 393: static int
! 394: dlattachreq(int fd, bpf_u_int32 ppa, int8_t *ebuf)
! 395: {
! 396: dl_attach_req_t req;
! 397:
! 398: req.dl_primitive = DL_ATTACH_REQ;
! 399: req.dl_ppa = ppa;
! 400:
! 401: return (send_request(fd, (int8_t *)&req, sizeof(req), "attach", ebuf, 0));
! 402: }
! 403:
! 404: static int
! 405: dlbindreq(int fd, bpf_u_int32 sap, int8_t *ebuf)
! 406: {
! 407:
! 408: dl_bind_req_t req;
! 409:
! 410: memset((int8_t *)&req, 0, sizeof(req));
! 411: req.dl_primitive = DL_BIND_REQ;
! 412: #ifdef DL_HP_RAWDLS
! 413: req.dl_max_conind = 1; /* XXX magic number */
! 414: /*
! 415: * 22 is INSAP as per the HP-UX DLPI Programmer's Guide
! 416: */
! 417: req.dl_sap = 22;
! 418: req.dl_service_mode = DL_HP_RAWDLS;
! 419: #else
! 420: req.dl_sap = sap;
! 421: #ifdef DL_CLDLS
! 422: req.dl_service_mode = DL_CLDLS;
! 423: #endif
! 424: #endif
! 425: return (send_request(fd, (int8_t *)&req, sizeof(req), "bind", ebuf, 0));
! 426: }
! 427:
! 428: static int
! 429: dlbindack(int fd, int8_t *bufp, int8_t *ebuf)
! 430: {
! 431: return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf));
! 432: }
! 433:
! 434: static int
! 435: dlokack(int fd, const int8_t *what, int8_t *bufp, int8_t *ebuf)
! 436: {
! 437: return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf));
! 438: }
! 439:
! 440: static int
! 441: dlinforeq(int fd, int8_t *ebuf)
! 442: {
! 443: dl_info_req_t req;
! 444:
! 445: req.dl_primitive = DL_INFO_REQ;
! 446:
! 447: return (send_request(fd, (int8_t *)&req, sizeof(req), "info", ebuf,
! 448: RS_HIPRI));
! 449: }
! 450:
! 451: static int
! 452: dlinfoack(int fd, int8_t *bufp, int8_t *ebuf)
! 453: {
! 454: return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf));
! 455: }
! 456:
! 457:
! 458: #ifdef HAVE_SYS_BUFMOD_H
! 459: static int
! 460: strioctl(int fd, int cmd, int len, int8_t *dp)
! 461: {
! 462: struct strioctl str;
! 463: int rc;
! 464:
! 465: str.ic_cmd = cmd;
! 466: str.ic_timout = -1;
! 467: str.ic_len = len;
! 468: str.ic_dp = dp;
! 469:
! 470: rc = ioctl(fd, I_STR, &str);
! 471: if (rc < 0)
! 472: {
! 473: return (rc);
! 474: }
! 475: else
! 476: {
! 477: return (str.ic_len);
! 478: }
! 479: }
! 480: #endif
! 481:
! 482:
! 483: #if (defined(DL_HP_PPA_ACK_OBS) && !defined(HAVE_HPUX11))
! 484: /*
! 485: * Under HP-UX 10, we can ask for the ppa
! 486: */
! 487: static int
! 488: get_dlpi_ppa(register int fd, register const int8_t *device, register int unit,
! 489: register int8_t *ebuf)
! 490: {
! 491: register dl_hp_ppa_ack_t *ap;
! 492: register dl_hp_ppa_info_t *ip;
! 493: register int i;
! 494: register u_int32_t majdev;
! 495: dl_hp_ppa_req_t req;
! 496: struct stat statbuf;
! 497: bpf_u_int32 buf[MAXDLBUF];
! 498:
! 499: if (stat(device, &statbuf) < 0)
! 500: {
! 501: sprintf(ebuf, "stat: %s: %s", device, strerror(errno));
! 502: return (-1);
! 503: }
! 504: majdev = major(statbuf.st_rdev);
! 505:
! 506: memset((int8_t *)&req, 0, sizeof(req));
! 507: req.dl_primitive = DL_HP_PPA_REQ;
! 508:
! 509: memset((int8_t *)buf, 0, sizeof(buf));
! 510: if (send_request(fd, (int8_t *)&req, sizeof(req), "hpppa", ebuf, 0) < 0 ||
! 511: recv_ack(fd, DL_HP_PPA_ACK_SIZE, "hpppa", (int8_t *)buf, ebuf) < 0)
! 512: {
! 513: return (-1);
! 514: }
! 515:
! 516: ap = (dl_hp_ppa_ack_t *)buf;
! 517: ip = (dl_hp_ppa_info_t *)((u_int8_t *)ap + ap->dl_offset);
! 518:
! 519: for (i = 0; i < ap->dl_count; i++)
! 520: {
! 521: if (ip->dl_mjr_num == majdev && ip->dl_instance_num == unit)
! 522: break;
! 523:
! 524: ip = (dl_hp_ppa_info_t *)((u_int8_t *)ip + ip->dl_next_offset);
! 525: }
! 526:
! 527: if (i == ap->dl_count)
! 528: {
! 529: sprintf(ebuf, "can't find PPA for %s", device);
! 530: return (-1);
! 531: }
! 532:
! 533: if (ip->dl_hdw_state == HDW_DEAD)
! 534: {
! 535: sprintf(ebuf, "%s: hardware state: DOWN\n", device);
! 536: return (-1);
! 537: }
! 538: return ((int)ip->dl_ppa);
! 539: }
! 540: #endif
! 541:
! 542: #ifdef HAVE_HPUX9
! 543: /*
! 544: * Under HP-UX 9, there is no good way to determine the ppa.
! 545: * So punt and read it from /dev/kmem.
! 546: */
! 547: static struct nlist nl[] =
! 548: {
! 549: #define NL_IFNET 0
! 550: { "ifnet" },
! 551: { "" }
! 552: };
! 553:
! 554: static int8_t path_vmunix[] = "/hp-ux";
! 555:
! 556: /*
! 557: * Determine ppa number that specifies ifname
! 558: */
! 559: static int
! 560: get_dlpi_ppa(register int fd, register const int8_t *ifname, register int unit,
! 561: register int8_t *ebuf)
! 562: {
! 563: register const int8_t *cp;
! 564: register int kd;
! 565: void *addr;
! 566: struct ifnet ifnet;
! 567: int8_t if_name[sizeof(ifnet.if_name)], tifname[32];
! 568:
! 569: cp = strrchr(ifname, '/');
! 570: if (cp != NULL)
! 571: {
! 572: ifname = cp + 1;
! 573: }
! 574: if (nlist(path_vmunix, &nl) < 0)
! 575: {
! 576: sprintf(ebuf, "nlist %s failed", path_vmunix);
! 577: return (-1);
! 578: }
! 579:
! 580: if (nl[NL_IFNET].n_value == 0)
! 581: {
! 582: sprintf(ebuf, "could't find %s kernel symbol", nl[NL_IFNET].n_name);
! 583: return (-1);
! 584: }
! 585:
! 586: kd = open("/dev/kmem", O_RDONLY);
! 587: if (kd < 0)
! 588: {
! 589: sprintf(ebuf, "kmem open: %s", strerror(errno));
! 590: return (-1);
! 591: }
! 592:
! 593: if (dlpi_kread(kd, nl[NL_IFNET].n_value, &addr, sizeof(addr), ebuf) < 0)
! 594: {
! 595: close(kd);
! 596: return (-1);
! 597: }
! 598: for (; addr != NULL; addr = ifnet.if_next)
! 599: {
! 600: if (dlpi_kread(kd, (off_t)addr, &ifnet, sizeof(ifnet), ebuf) < 0 ||
! 601: dlpi_kread(kd, (off_t)ifnet.if_name,
! 602: if_name, sizeof(if_name), ebuf) < 0)
! 603: {
! 604: close(kd);
! 605: return (-1);
! 606: }
! 607: sprintf(tifname, "%.*s%d",
! 608: (int)sizeof(if_name), if_name, ifnet.if_unit);
! 609: if (strcmp(tifname, ifname) == 0)
! 610: {
! 611: return (ifnet.if_index);
! 612: }
! 613: }
! 614:
! 615: sprintf(ebuf, "Can't find %s", ifname);
! 616: return (-1);
! 617: }
! 618:
! 619: static int
! 620: dlpi_kread(register int fd, register off_t addr, register void *buf,
! 621: register u_int len, register int8_t *ebuf)
! 622: {
! 623: register int cc;
! 624:
! 625: if (lseek(fd, addr, SEEK_SET) < 0)
! 626: {
! 627: sprintf(ebuf, "lseek: %s", strerror(errno));
! 628: return (-1);
! 629: }
! 630: cc = read(fd, buf, len);
! 631: if (cc < 0)
! 632: {
! 633: sprintf(ebuf, "read: %s", strerror(errno));
! 634: return (-1);
! 635: }
! 636: else if (cc != len)
! 637: {
! 638: sprintf(ebuf, "int16_t read (%d != %d)", cc, len);
! 639: return (-1);
! 640: }
! 641: return (cc);
! 642: }
! 643: #endif
! 644:
! 645: #define ETHERADDRL 6
! 646: struct EnetHeaderInfo
! 647: {
! 648: struct libnet_ether_addr DestEtherAddr;
! 649: u_int16_t EtherFrameType;
! 650: };
! 651:
! 652:
! 653: int
! 654: libnet_close_link(libnet_t *l)
! 655: {
! 656: if (close(l->fd) == 0)
! 657: {
! 658: free(l);
! 659: return (1);
! 660: }
! 661: else
! 662: {
! 663: free(l);
! 664: return (-1);
! 665: }
! 666: }
! 667:
! 668: #ifdef HAVE_HPUX11
! 669: int
! 670: libnet_write_link(libnet_t *l, u_int8_t *packet, u_int32_t size)
! 671: {
! 672: struct strbuf data, ctl;
! 673: dl_hp_rawdata_req_t *rdata;
! 674: int c;
! 675:
! 676: if (l == NULL)
! 677: {
! 678: return (-1);
! 679: }
! 680:
! 681: rdata = (dl_hp_rawdata_req_t *)ctlbuf;
! 682: rdata->dl_primitive = DL_HP_RAWDATA_REQ;
! 683:
! 684: /* send it */
! 685: ctl.len = sizeof(dl_hp_rawdata_req_t);
! 686: ctl.maxlen = sizeof(dl_hp_rawdata_req_t);
! 687: ctl.buf = (int8_t *)rdata;
! 688:
! 689: data.maxlen = size;
! 690: data.len = size;
! 691: data.buf = packet;
! 692:
! 693: c = putmsg(l->fd, &ctl, &data, 0);
! 694: if (c == -1)
! 695: {
! 696: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
! 697: "libnet_write_link(): %d bytes written (%s)\n", c,
! 698: strerror(errno));
! 699: return (-1);
! 700: }
! 701: else
! 702: {
! 703: return (size);
! 704: }
! 705: }
! 706: #else
! 707: int
! 708: libnet_write_link(libnet_t *l, u_int8_t *packet, u_int32_t size)
! 709: {
! 710: int c;
! 711: struct strbuf data;
! 712:
! 713: if (l == NULL)
! 714: {
! 715: return (-1);
! 716: }
! 717:
! 718: data.maxlen = size;
! 719: data.len = size;
! 720: data.buf = packet;
! 721:
! 722: c = putmsg(l->fd, NULL, &data, 0);
! 723: if (c == -1)
! 724: {
! 725: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
! 726: "libnet_write_link: %d bytes written (%s)\n", c,
! 727: strerror(errno));
! 728: return (-1);
! 729: }
! 730: else
! 731: {
! 732: return (size);
! 733: }
! 734: }
! 735: #endif
! 736:
! 737: struct libnet_ether_addr *
! 738: libnet_get_hwaddr(libnet_t *l)
! 739: {
! 740: int8_t buf[2048];
! 741: union DL_primitives *dlp;
! 742: struct libnet_ether_addr *eap;
! 743:
! 744: if (l == NULL)
! 745: {
! 746: return (NULL);
! 747: }
! 748:
! 749: dlp = (union DL_primitives *)buf;
! 750:
! 751: dlp->physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ;
! 752: dlp->physaddr_req.dl_addr_type = DL_CURR_PHYS_ADDR;
! 753:
! 754: if (send_request(l->fd, (int8_t *)dlp, DL_PHYS_ADDR_REQ_SIZE, "physaddr",
! 755: l->err_buf, 0) < 0)
! 756: {
! 757: return (NULL);
! 758: }
! 759: if (recv_ack(l->fd, DL_PHYS_ADDR_ACK_SIZE, "physaddr", (int8_t *)dlp,
! 760: l->err_buf) < 0)
! 761: {
! 762: return (NULL);
! 763: }
! 764:
! 765: eap = (struct libnet_ether_addr *)
! 766: ((int8_t *) dlp + dlp->physaddr_ack.dl_addr_offset);
! 767: return (eap);
! 768: }
! 769:
! 770: /* EOF */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>