Avatar billede kov Nybegynder
19. marts 2001 - 16:43 Der er 6 kommentarer og
1 løsning

Læsning af MAC adresse

Hvordan kan jeg læse MAC-adressen (IA address) på netkortet fra et C/C++ program i dos mode?

Jeg har læst og studeret spørgsmål 16447 fra \"Andersb\" og det tilhørende svar fra \"privaten\". Men det opfylder ikke rigtigt mine krav  =:(

Jeg ønsker en funktion der læser direkte i hardware registrene på net-controlleren eller BIOS....

Avatar billede wisen Nybegynder
20. marts 2001 - 09:19 #1
Prøv at kikke her : http://community.borland.com/article/0,1410,26040,00.html
Avatar billede kov Nybegynder
20. marts 2001 - 16:11 #2
>> wisen: Det er en udemærket side der er henvist til. Læsning af MAC adressen (og meget andet fra net-adapteren) gennem API og netBIOS kald gennemgås med gode eksempler. Desværre er et eksempel på direkte læsning af Ethernet controlleren ikke vist. Jeg vil alligevel gerne give 15-20 point for linket -men hvordan?

Hvis nogen kan fortælle mig hvordan man mere generelt finder I/O området for et PCI PnP kort, hvilket må give adgang til net-controllerens register vil det hjælpe meget. 

<< KOV
Avatar billede wisen Nybegynder
21. marts 2001 - 09:15 #3
Hvis du mener, at du vil give mig 15-20 point, kan du enten oprettet et nyt spg, eller under pointgivningen tage avanceret/udvidet (kan ikke lige huske hvad knappen hedder).

Jeg kender ikke lige til steder, hvor der er noget med direkte tilgang til et netkort. Det kan jeg vist ikke hjælpe dig med :(
Avatar billede soepro Nybegynder
21. marts 2001 - 10:14 #4
Hvis du skal have fat i det aktuelle I/O område for et PnP kort, findes der nogle bios interrupt kald der kan returnere dem til dig - forudsat at du kender kortets ID.

Jeg har følgende lidt lange eksempel på hvordan man finder den for et PCI I/O kort fra Arcom. Det er FIND_PCIDEVICE funktionen der er interessant for dig.

/* ************************************************************************ *
* apci.c -    PCI Access Demo program                                    *
*                                                                          *
* $Author      DGS$                                                        *
* $Log$                                                                    *
*                                                                          *
* Modification History                                                    *
* 1-03-98  DGS  1                                                        *
* - Created using BorlandC 4.5.                                            *
* ************************************************************************ */

/******************************* Include Files ******************************/

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <dos.h>

/**************************** General Definitions ***************************/

#define        FALSE                0         
#define        TRUE                (!FALSE)  /* TRUE equals not FALSE */

#define        PCI                 0x1A      /* PCI Interrupt */
#define        PLX                0x10B5    /* PLX Technology vendor ID */
#define        PCI9050            0x9050      /* PCI9050 ID */
#define        BASEADDRREG        0x18      /* Base Address register */
#define        SUBVENDOR        0x2C      /* Subsystem Vendor ID */
#define        SUBID                0x2E      /* Subsystem ID */
#define        INTLINE            0x3C          /* Interrupt Line assigneded */
#define        INTPIN            0x3D          /* PCI Interrupt Pin */   
#define        ARCOM                0x13AB      /* ARCOM\'s Vendor ID */   

#define        USERLED        0x80      /* User LED Index register */
#define        LEDON                0x01      /* LED ON */
#define        LEDOFF            0x00      /* LED OFF */

/**************************** Board Definitions ******************************/

#define        IB40                0x591        /* APCI-IB40 */
#define        SER4                0x592    /* APCI-SER4 */
#define        RELAY8            0x594    /* APCI-RELAY8/IN8 */
#define        ADADIO            0x605    /* APCI-ADADIO */

/****************************** Global Variables ****************************/

int    NOBOARD = TRUE;        /* ARCOM PCI not found*/
int    ERROR = FALSE;            /* Global Error Flag */

union REGS inregs, outregs;

/* Definitions so that BYTE is 8-bits, WORD is 16-bits, and DWORD is 32-bits */

typedef unsigned char    BYTE ;
typedef unsigned short    WORD ;
typedef unsigned long    DWORD ;

/****************************** Function Prototypes *************************/

void main (void);
WORD FIND_PCI_DEVICE(WORD device, WORD vendor, WORD index);
WORD READ_CONFIG_WORD(WORD PCIdevice, BYTE Regnum);
WORD READ_CONFIG_BYTE(WORD PCIdevice, BYTE Regnum);
void WRITE_CONFIG_WORD(WORD PCIdevice, BYTE Regnum, WORD Value);
void Verifyboard(WORD board);
WORD IOaddrange(WORD PCIdevice);
void Testboard(WORD base, WORD board);
void IoWrite(int base, int ioaddr, int value);

/******************************** Main Program ******************************/

void main(void)
{
    int c;
    int Index = 0;      /* Instance of device */
    WORD PCIdevice;    /* Bus number, Device nuber and Function number */
    WORD board;        /* APCI board ID */
    WORD regval;        /* Register Value */
    WORD base;          /* Base address */

    clrscr();
    printf(\"Arcom PCI board detection utility Version 1.0\\n\\n\");  /* Signon message */

    while(ERROR==FALSE)
    {   
    PCIdevice = (FIND_PCI_DEVICE(PCI9050, PLX, Index));    /* Find PCI device */
    if (ERROR == TRUE)
            break;

    NOBOARD=FALSE;                                                      /* At least 1 board with PLX device detected */
   
    regval = (READ_CONFIG_WORD(PCIdevice, SUBVENDOR));    /* Read Subvendor ID */
    if (ERROR == TRUE)
            break;

    if (regval == ARCOM)                                  /* Check Vendor is Arcom */
            {
            board = READ_CONFIG_WORD(PCIdevice, SUBID);      /* Read  Subsystem ID */
           
            Verifyboard(board);                              /* Check board and display meaasge */

            base = IOaddrange(PCIdevice);                    /* Check address range */

            regval=READ_CONFIG_BYTE(PCIdevice, INTPIN);      /* Detect if device has IRQ */

            if (regval != 0)
                {
                regval=READ_CONFIG_BYTE(PCIdevice, INTLINE);  /* Detect IRQ routing */
                printf(\"\\tInterrupt\\tIRQ%d\\n\",regval);
                }

            printf(\"\\nTest Board access Y/N ?\");          /* Ask if user wants to test board */
            c=getch();
           
            if ((c=toupper(c))==\'Y\')
                {
                    Testboard(base,board);                  /* Flash board LED */
                }
            else
                {
                    printf(\"\\n\\n\");                              /* Format display correctly */   
                }
            }
    ++Index;                                                          /* Increase index and search for next device */       
    }
    if (NOBOARD==TRUE)   
        printf(\"No Arcom PCI boards detected\\n\");
   
}

/*****************************************************************************
* Find_pci_device -  Uses INT 1A to find a specified PCI device            *
*                                                                          *
* parameters passed    : Device - PCI chip                                  *
*                        Vendor - Manufacturers ID                          *
*                        Index  - Instance of device                        *
* Return values        : PCIdevice - bus, device and function number        *
****************************************************************************/

WORD FIND_PCI_DEVICE(WORD device, WORD vendor, WORD index)
{
    WORD    PCIdevice = 0;

    inregs.h.ah = 0xb1;         /* PCI function ID */
    inregs.h.al = 0x02;         /* FIND_PCI_DEVICE Function */
    inregs.x.cx = device;  /* Device ID */
    inregs.x.dx = vendor;  /* Vendor ID */
    inregs.x.si = index;    /* Instance of device */

    int86(PCI, &inregs, &outregs); /* PCI Interrupt call */

    if((outregs.h.ah) == 0x86)
        ERROR = TRUE;
    else
        PCIdevice = outregs.x.bx;

    return (PCIdevice);
}


/*****************************************************************************
* Read_Config_Word -  Uses INT 1A to read a specified word                  *
*                                                                          *
* parameters passed    : PCIdevice - bus, device and function number        *
*                               Regnum - register to read                          *
* Return values        : Regval - Value returned from register              *
****************************************************************************/

WORD READ_CONFIG_WORD(WORD PCIdevice, BYTE Regnum)
{
    WORD    Regval;

    inregs.h.ah = 0xb1;             /* PCI function ID */
    inregs.h.al = 0x09;             /* READ_CONFIG_WORD Function */
    inregs.x.bx = PCIdevice;  /* Device */
    inregs.x.di = Regnum;        /* Register number to read */

    int86(PCI, &inregs, &outregs); /* PCI Interrupt call */

    if (outregs.h.ah == 0x87)
        {
        printf(\"Error = BAD_REGISTER_NUMBER\\n\");
        ERROR = TRUE;
        }
    else
        Regval = outregs.x.cx;

    return (Regval);
}

/*****************************************************************************
* Read_Config_Byte -  Uses INT 1A to read a specified byte                  *
*                                                                          *
* parameters passed    : Regnum - Register to write                        *
*                                  Value - Value to be written                        *                       
* Return values        : Regval - value read                                *
****************************************************************************/

WORD READ_CONFIG_BYTE(WORD PCIdevice, BYTE Regnum)
{
    BYTE    Regval;

    inregs.h.ah = 0xb1;             /* PCI function ID */
    inregs.h.al = 0x08;             /* READ_CONFIG_WORD Function */
    inregs.x.bx = PCIdevice;  /* Device */
    inregs.x.di = Regnum;        /* Register number to read */

    int86(PCI, &inregs, &outregs); /* PCI Interrupt call */

    if (outregs.h.ah == 0x87)
        {
        printf(\"Error = BAD_REGISTER_NUMBER\\n\");
        ERROR = TRUE;
        }
    else
        Regval = outregs.h.cl;
           
    return (Regval);
}

/*****************************************************************************
* Write_Config_Word -  Uses INT 1A to wrie a specified word                *
*                                                                          *
* parameters passed    : PCIdevice - Bus, device and function number        *
*                                  Regnum - Register to write                        *
*                                  Value - Value to be written                        *
* Return values        : None                                              *
****************************************************************************/

void WRITE_CONFIG_WORD(WORD PCIdevice, BYTE Regnum, WORD Value)
{
    inregs.h.ah = 0xb1;             /* PCI function ID */
    inregs.h.al = 0x0c;             /* WRITE_CONFIG_WORD Function */
    inregs.x.bx = PCIdevice;  /* Device */
    inregs.x.di = Regnum;        /* Register number to write */
    inregs.x.cx = Value;

    int86(PCI, &inregs, &outregs); /* PCI Interrupt call */

    if (outregs.h.ah == 0x87)
        {
        printf(\"Error = BAD_REGISTER_NUMBER\\n\");
        ERROR = TRUE;
        }
}

/*****************************************************************************
* Verifyboard  -  Checks which board has been found and prints a message to *
*                the display                                              *
* parameters passed    : Board - name of board found                        *
* Return values        : None                                              *
****************************************************************************/

void Verifyboard (WORD board)
{
    printf(\"\\tPCI Board\\t\");

    switch(board)
        {
        case IB40     :printf(\"APCI-IB40\\n\");
                          break;
        case SER4     :printf(\"APCI-SER4\\n\");
                          break;   
        case RELAY8 :printf(\"APCI-RELAY8/IN8\\n\");
                          break;
        case ADADIO :printf(\"APCI-ADADIO\\n\");
                          break;                         
        default        :printf(\"UNKNOWN\\n\");
                          break;   
        }
}

/*****************************************************************************
* IOaddrange  -  Determines I/O address range allocated to PCI card        *
*                                                                          *
* parameters passed    : PCIdevice - Bus, device and Function number        *
* Return values        : lower - Base address                              *
****************************************************************************/

WORD IOaddrange(WORD PCIdevice)
{
    WORD lower, upper;

    lower = READ_CONFIG_WORD(PCIdevice, BASEADDRREG);  /* Read Base addr register */
    WRITE_CONFIG_WORD(PCIdevice, BASEADDRREG,0xFFFF);  /* Write all 1\'s to base addr register */
    upper = READ_CONFIG_WORD(PCIdevice, BASEADDRREG);  /* Read base addr register */
    WRITE_CONFIG_WORD(PCIdevice, BASEADDRREG, lower);  /* Restore orignal value */
    --lower;                                          /* Strip off I/O bit */
    --upper;
    upper = ~upper;                                    /* Invert upper */
    upper = upper + lower;                            /* Add to base addr to give range */
    printf(\"\\tAddrees Range\\t%xH - %xH\\n\",lower,upper);

    return(lower);                                                    /* Return base address */   

}

/*****************************************************************************
* Testboard  -  Flashes user led until key is pressed                      *
*                                                                          *
* parameters passed    : Base - base address of board                      *
*                        Board - board name                                *
* Return values        : None                                              *
****************************************************************************/
void Testboard(WORD base, WORD board)

{
        if (board == RELAY8)
            {
                printf(\"\\n\\nThe RED ACCESS LED should be ON, press any key to turm OFF\\n\\n\");
                while(!kbhit())
                    {
                        IoWrite(base,0,0);
                    }   
                getch();
            }

        else
            {
                printf(\"\\n\\nThe GREEN user LED shoud be flashing, press any Key to continue.\\n\\n\");
   
                while (!kbhit())
                    {
                        IoWrite(base,USERLED, LEDON);  /* Turn User LED ON */
                        delay(500);                    /* Wait 500ms */
                        IoWrite(base,USERLED, LEDOFF);  /* Turn user LED OFF */
                        delay(500);                    /* Wait 500ms */
                    }
                getch();
            }
}

/***************************************************************************
* IoWrite - write to the port.                                            *
*                                                                          *
* Paramters passed : BASE  - base address of board under test.            *
*                    ioaddr - address pointer to the port.                *
*                    value  - data to be output.                          *
* Return          : None.                                                *
****************************************************************************/

void IoWrite(int base, int ioaddr, int value)
{
    outp(base,ioaddr);          /* Set up I/O address */
    outp(base+1,value);        /* Write value to I/O address */
}

Avatar billede kov Nybegynder
22. marts 2001 - 08:46 #5
>> soepro Tak for det gode eksempel, har du virkelig forfattet det for min skyld?? ;)
Avatar billede soepro Nybegynder
22. marts 2001 - 09:13 #6
Nej, jeg har fået det fra producenten af I/O kortet for ½ års tid tilbage, og selv lavet modificationer til det, så jeg kunne bruge det i min applikation. Ovenstående er simpelthen blot den oprindelige code - med venlig hilsen Arcom Control Systems Inc. i England - besøg dem på http://www.arcom.co.uk
Avatar billede kov Nybegynder
22. marts 2001 - 10:52 #7
>> soepro Jeg havde nok gættet at det ikke var dit eget værk (navnene PLX og Arcom går igen flere gange, og deres Vendor ID\'er er jo brugt). Kommentaren gik mere på længden....

Jeg har kigget på Arcom\'s side, der ligger jo faktisk en del guld og venter. Dit eksempel har allerede været til stor hjælp og er så absolut de 60 point værd :) 

Igen tak for hjælpen
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester