/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Data Link API - Make Address */ #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include #include #include #include #include extern struct dl_descriptor *_getdesc(); struct dl_address * dl_allocaddr(fd, which) { struct dl_address *addr; struct dl_descriptor *dl; int alen; dl = _getdesc(fd); if (dl == NULL){ errno = EBADF; return NULL; }; addr = (struct dl_address *)malloc(sizeof(struct dl_address)); if (addr == NULL){ dl->error = DLSYSERR; return NULL; } if (which & DL_DST){ addr->dla_dmax = 16; addr->dla_daddr = (unsigned char *)malloc(addr->dla_dmax); if (addr->dla_daddr == NULL){ int err; err = errno; free(addr); errno = err; dl->error = DLSYSERR; return NULL; } } if (which & DL_SRC){ addr->dla_smax = 16; addr->dla_saddr = (unsigned char *)malloc(addr->dla_smax); if (addr->dla_saddr == NULL){ int err; err = errno; if (addr->dla_slen > 0){ free(addr->dla_saddr); } free(addr); errno = err; dl->error = DLSYSERR; return NULL; } } return addr; } /* destination address only */ struct dl_address * dl_mkaddress(fd, addr, sap, oi, oitype) unsigned char *addr; unsigned char *oi; { struct dl_address *da; struct dl_descriptor *dl; dl = _getdesc(fd); if (dl == NULL) return NULL; da = dl_allocaddr(fd, DL_DST); if (da == NULL) return NULL; memcpy(da->dla_daddr, addr, 6); if (sap > 1500){ da->dla_dlen = 8; *(unsigned short *)(da->dla_daddr + 6) = sap; return da; } else if (sap < 512){ da->dla_dlen = 7; *(da->dla_daddr+6) = sap; return da; } dl->error = DLBADSAP; return NULL; } #if defined(DLPI_1) dl_parseaddr(addr, len, paddr, sap, oi, oitype) unsigned char *addr, *paddr, *oi; long *sap, *oitype; { if (addr == NULL) return -1; if (paddr){ memcpy(paddr, addr, 6); } if (sap){ switch(len){ case 8: *sap = *(unsigned short *)(addr + 6); break; case 7: case 12: *sap = *(unsigned char *)(addr + 6); if (*sap == 0xAA){ if (len != 12) return -1; if (oi) memcpy(oi, addr + 7, 3); if (oitype) *oitype = *(unsigned short *)(addr + 10); } break; default: return -1; } } return 0; } #else dl_parseaddr(addr, len, paddr, sap, oi, oitype) unsigned char *addr, *paddr, *oi; long *sap, *oitype; { if (addr == NULL) return -1; if (paddr){ memcpy(paddr, addr, 6); } if (sap){ switch(len){ case 8: *sap = *(unsigned short *)(addr + 6); break; case 7: case 12: *sap = *(unsigned char *)(addr + 6); if (*sap == 0xAA){ if (len != 12) return -1; if (oi) memcpy(oi, addr + 7, 3); if (oitype) *oitype = *(unsigned short *)(addr + 10); } break; default: return -1; } } return 0; } #endif