/*--------------------------------------------------------------------------- * Filename: ilan.c (was pefconfig.c) * * Author: arcress at users.sourceforge.net * Copyright (c) 2009 Kontron America, Inc. * * Abstract: * This tool sets up the custom Platform Event Filter for the panicSEL * record (0x20, OS Critical Stop) to send a PEF SNMP alert for Linux * panics. It also configures the BMC LAN parameters, which are needed * to support PEF alerts. * * ----------- Change History ----------------------------------------------- * 10/16/01 Andy Cress - created * 10/24/01 Andy Cress - mods for SetPefEntry(0c) * 11/02/01 Andy Cress - added option to disable a given PefEntry * 11/15/01 Andy Cress - added function to GetLanEntry * 11/19/01 Andy Cress - added function to SetLanEntry * 01/18/02 Andy Cress - added GetCfgData function * 01/31/02 Andy Cress - converted to use ipmi_cmd_ia * 02/06/02 Andy Cress - removed GetCfgData * 02/06/02 Andy Cress - added ipmi_cmd_va * 02/08/02 Andy Cress - added GetChanAcc * 02/14/02 Andy Cress - added Get_IPMac_Addr() * 02/21/02 Andy Cress - added Alert IP/MAC logic to Get_IPMac_Addr() * 03/21/02 Andy Cress - do SetChanAcc(0x80) with every SetChanAcc(0x40) * 04/15/02 Andy Cress v1.2 - fix bug with user-specified Alert IP: * (ccode=c7 on SetLanEntry(16 & 18), also * added Get_Mac() for user-specified Alert IP. * 04/16/02 Andy Cress v1.3 added SetUser() to set password if specified, * also changed unset mac[0] to be 0xFF, not 0. * 05/09/02 Andy Cress v1.4 fixed bug 504 gwymac[0]=00 (mymac overwrote it), * also fixed alert scan to pick last trapsink * 05/31/02 Andy Cress v1.5 for gwy mac, changed arping -c 1 to -c 2, * also get com2sec community from snmpd.conf, * set dest type for no ack, no retry, * special handling to set preset PEF entries * 07/02/02 Andy Cress v1.6 added more Usage text * 07/08/02 Andy Cress v1.7 SetUserAccess length change * 08/02/02 Andy Cress v1.8 moved common ipmi_cmd() code to ipmicmd.c * 08/27/02 Andy Cress v1.9 fixed 0xc7 on SETUSER_ACCESS with pefconfig -P "", * show message if alert dest not found * 09/10/02 Andy Cress v1.10 make channel nums into defines (16) * 09/17/02 Andy Cress v1.11 decode Dest Addr IP (19) in decimal, * fix enable user padding in SetUser, * display new community string when setting * 12/09/02 Andy Cress v1.12 fix error w -C & snmpd.conf conflict * 01/29/03 Andy Cress v1.13 added MV OpenIPMI support * 02/05/03 Andy Cress v1.14 show pef entry descriptions, * added EnablePef routine * show correct Alert dest mac if -A only * 04/04/03 Andy Cress v1.15 add eth interface option (-i) * 05/13/03 Andy Cress v1.16 fix EnablePef if startup delay not supported * 06/19/03 Andy Cress v1.17 added errno.h (email from Travers Carter) * 07/25/03 Andy Cress v1.18 add SerialOverLan configuration * mod to SetUser, added GetBmcEthDevice, * use 'arping -I' if eth1. * 08/18/03 Andy Cress v1.19 Don't abort if IPMI 1.0, just skip PEF, * SetLanEntry(10 & 11) for bmc grat arp, * SetLanEntry(2) to 0x17 for auth priv * 09/10/03 Andy Cress v1.20 Don't enable a PEF entry if it is empty, * added -L lan_ch parameter, * scan for lan_ch in GetBmcEthDevice * 09/22/03 Andy Cress v1.21 Add DHCP option (-D), from Jerry Yu. * 12/05/03 Andy Cress v1.22 Fix auth type enables for ServerConfig * 12/16/03 Andy Cress v1.23 Allow flexible auth types via authmask * 03/19/04 Andy Cress v1.24 Change default pefnum for mBMC to 10 * 04/15/04 Andy Cress v1.25 Init each response for channel info, avoids * 0xcc error with /dev/ipmi0 due to wrong lan_ch * 05/05/04 Andy Cress v1.26 call ipmi_close before exit. Note that * Get_IPMac_Addr and GetBmcEthDevice * routines need more work for WIN32. * 05/24/04 Andy Cress v1.27 added CHAN_ACC params for ia64 * 06/28/04 Andy Cress v1.28 added parsing to get community from trapsink * 07/23/04 Andy Cress v1.29 use lan_ch variable to set Alert Policy Table * 08/23/04 Andy Cress v1.30 fixed decoding of PE Table entries, * added -e option (same as no params) * 08/25/04 Andy Cress v1.31 added some WIN32 logic to Get_Mac, Get_IPMac_Addr * 11/01/04 Andy Cress v1.32 add -N / -R for remote nodes * added -U for remote username * 11/18/04 Andy Cress v1.33 added -u to configure a lan username (user 2) * 11/23/04 Andy Cress v1.34 added pef_defaults if first 11 empty * 01/11/05 Andy Cress v1.35 allow scan for BMC LAN if fIPMI10 * 01/20/05 Andy Cress v1.36 fix to allow IPMI 2.0 * 02/16/05 Andy Cress v1.37 added IPMI 2.0 VLAN parameters, * if DHCP, can set DHCP Server via -I param * 03/02/05 Andy Cress v1.38 show Serial-Over-Lan params, * fix -L with lan_ch_parm. mods to GetBmcEthDevice * 03/18/05 Andy Cress v1.39 fix GetBmcEthDevice for invalid MAC compares * 06/03/05 Andy Cress v1.40 For my MAC in BMC, check user-specified, then check existing BMC MAC, then check OS MAC. * 06/10/05 Andy Cress v1.41 Display multiple Alert Destinations, * handle fSOL20 commands * 07/07/05 Andy Cress v1.42 Fix GetBmcEthDevice for TIGI2U to skip GCM ch 3 * 07/08/05 Andy Cress v1.43 Mods to handle Intel NSI2U miniBMC, * 08/01/05 Andy Cress v1.44 added -t option to test if BMC LAN configured * 08/10/05 Andy Cress v1.45 truncate extra string chars, * decode more PEF params * 09/07/05 Andy Cress v1.46 enable mBMC PEF entries 26 thru 30 * 04/06/06 Andy Cress v1.47 show "gcm" as ifname if -L 3. * 06/20/06 Andy Cress v1.48 fix strcmp(gcm), show all 4 alert policies, * add PefDesc() for misc vendor pefdesc, add -a. * 08/08/06 Andy Cress v1.49 add Alcolu to fsharedMAC * 09/29/06 Andy Cress v1.52 use bmcmymac if valid, use bmcmyip if ok, * added -q for user number, * enhanced Get_IPMac_Addr for Windows * 10/12/06 Andy Cress v1.53 FindEthNum updates, always use gwy iface for mac * 11/02/06 Andy Cress v1.55 add user names, EnablePef mods for non-Intel. * 05/02/07 Brian Johnson v1.65 add fpefenable flag to not do SetPefEntry * if no Alert Destination. Previously did * SetPefEntry but not EnablePef in this case. * 05/04/07 Andy Cress v1.65 Use 0x02 for DHCP source instead of 0x03, * fix 1714748 missing "X:" in getopt line * 05/23/07 Jakub Gorgolewski * v1.66 Use iphlpapi for Windows detection * 10/31/07 Andy Cress v2.3 Fixed PEF entry for Power Redundancy Lost * 11/15/07 Andy Cress v2.4 Move custom PEF to #14, add to usage, * Allow broadcast MAC for -X * 12/17/07 Andy Cress v2.5 Add fSetPEFOks & secondary Gateway */ /*M* *--------------------------------------------------------------------------- Copyright (c) 2009 Kontron America, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: a.. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. b.. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. c.. Neither the name of Kontron nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *--------------------------------------------------------------------------- *M*/ #ifdef WIN32 #include #include #include #include #include #include #include "getopt.h" #elif defined(DOS) #include #include #include #include #include "getopt.h" #else /* Linux or similar */ #include #include #include #include #include #if defined(HPUX) /* getopt is defined in stdio.h */ #elif defined(MACOS) /* getopt is defined in unistd.h */ #include #else #include #endif #include #include #include #include #include #endif #ifdef LINUX #include #endif #ifdef SOLARIS #include #define SIOCGIFHWADDR SIOCGENADDR #define ifr_netmask ifr_ifru.ifru_addr // #define ifr_hwaddr.sa_data ifr_ifru.ifru_enaddr #elif defined(BSD) #include #define SIOCGIFHWADDR SIOCGIFMAC #define ifr_netmask ifr_ifru.ifru_addr // #define ifr_hwaddr.sa_data ifr_ifru.ifru_addr #elif defined(MACOS) #include #define ifr_netmask ifr_ifru.ifru_addr #endif #include "ipmicmd.h" #include "oem_intel.h" #include "oem_supermicro.h" #define SELprintf printf #define RTF_UP 0x0001 /* route usable */ #define SOL_ENABLE_FLAG 0x01 #define SOL_DISABLE_FLAG 0x00 #define SOL_PRIVILEGE_LEVEL_USER 0x02 #define SOL_PRIVILEGE_LEVEL_OPERATOR 0x03 #define SOL_PRIVILEGE_LEVEL_ADMIN 0x04 #define SOL_PREFERRED_BAUD_RATE 0x0a /*115.2k*/ /* For IPMI 1.5, use Intel SOL commands & subfunctions */ #define SOL_ENABLE_PARAM 0x01 #define SOL_AUTHENTICATION_PARAM 0x02 #define SOL_ACC_INTERVAL_PARAM 0x03 #define SOL_RETRY_PARAM 0x04 #define SOL_BAUD_RATE_PARAM 0x05 /*non-volatile*/ #define SOL_VOL_BAUD_RATE_PARAM 0x06 /*volatile*/ /* For IPMI 2.0, use IPMI SOL commands & subfunctions */ #define SOL_ENABLE_PARAM2 0x08 #define SOL_AUTHENTICATION_PARAM2 0x09 #define SOL_BAUD_RATE_PARAM2 0x11 /* IPMI 2.0 SOL PAYLOAD commands */ #define SET_PAYLOAD_ACCESS 0x4C #define GET_PAYLOAD_ACCESS 0x4D #define GET_PAYLOAD_SUPPORT 0x4E /* Channel Access values */ #define CHAN_ACC_DISABLE 0x20 /* PEF off, disabled*/ #define CHAN_ACC_PEFON 0x02 /* PEF on, always avail */ #define CHAN_ACC_PEFOFF 0x22 /* PEF off, always avail*/ /* special channel access values for ia64 */ #define CHAN_ACC_PEFON64 0x0A /* PEF on, always avail, UserLevelAuth=off */ #define CHAN_ACC_PEFOFF64 0x2A /* PEF off, always avail, UserLevelAuth=off */ #define OS_LINUX 1 #define OS_WINDOWS 2 #define OS_SOLARIS 3 #define OS_BSD 4 #define OS_HPUX 5 /* TSRLT2 Channels: 0=IPMB, 1=Serial/EMP, 6=LAN2, 7=LAN1 */ /* S5000 Channels: 0=IPMB, 1=LAN1, 2=LAN2, 3=RMM2, 4=Serial, 6=pci, 7=sys */ /* For TIGPT1U/mBMC: 1=LAN channel, no serial */ #define LAN_CH 1 #define SER_CH 4 #define MAXCHAN 12 /*was 16, reduced for gnu ipmi_lan*/ #define NUM_DEVICES_TO_CHECK 32 /*for GetBmcEthDevice()*/ #define MAC_LEN 6 /*length of MAC Address*/ #define PSW_LEN 16 /* see also PSW_MAX =20 in ipmicmd.h*/ /* Note: The optional IPMI 2.0 20-byte passwords are not supported here, * due to back-compatibility issues. */ /* IP address source values */ #define SRC_STATIC 0x01 #define SRC_DHCP 0x02 /* BMC running DHCP */ #define SRC_BIOS 0x03 /* BIOS, sometimes DHCP */ #define SRC_OTHER 0x04 /* PEF event severities */ #define PEF_SEV_UNSPEC 0x00 #define PEF_SEV_MON 0x01 #define PEF_SEV_INFO 0x02 #define PEF_SEV_OK 0x04 #define PEF_SEV_WARN 0x08 #define PEF_SEV_CRIT 0x10 #define PEF_SEV_NORECOV 0x20 #define FLAG_INIT 99 /*initial value of char flag, beyond scope*/ #define PARM_INIT 0xff typedef struct { /* See IPMI Table 15-2 */ uchar rec_id; uchar fconfig; uchar action; uchar policy; uchar severity; uchar genid1; uchar genid2; uchar sensor_type; uchar sensor_no; uchar event_trigger; uchar data1; uchar mask1; uchar res[9]; } PEF_RECORD; typedef struct { /* See IPMI Table 19-3 */ uchar data[36]; } LAN_RECORD; /*LanRecord*/ #ifdef METACOMMAND extern int get_lan_stats(uchar chan); /*see bmchealth.c */ extern char *get_sensor_type_desc(uchar stype); /*from ievents.c*/ #endif #define MYIP 0x01 #define GWYIP 0x02 #define DESTIP 0x04 #define MAXPEF 41 /* max pefnum offset = 40 (41 entries) */ /* * Global variables */ static char * progver = "2.94"; static char * progname = "ilan"; static char fdebug = 0; static char fipmilan = 0; static char fIPMI10 = 0; /* =1 if IPMI v1.0 or less */ static char fIPMI20 = 0; /* =1 if IPMI v2.0 or greater */ static char fSOL20 = 1; /* =1 if use Serial-Over-Lan 2.0 w IPMI 2.0 */ static char fsharedMAC = 0; /* =1 if special shared-MAC BMC LAN port */ static char fAdjustPefNum = 0; /* =1 adjust pefnum to first empty index */ static char fUserPefNum = 0; /* =1 if user specified a valid pefnum value*/ static char freadonly = 1; /* =1 to only read LAN & PEF parameters */ static char fcanonical = 0; /* =1 to show only canonical output */ static char flansecure = 0; /* =1 set lan security: no null, cipher0 off*/ static char bdelim = BCOLON; /* delimiter ':' or '|' if canonical output*/ static char ftestonly = 0; static char fprivset = 0; static char flanstats = 0; /* =1 to show the IPMI LAN statistics */ static char foptmsg = 0; /* =1 to show the option warning msg */ static char fshowchan = 0; /* =1 to show the IPMI channels */ static char nopts = 0; /* number of pefconfig options specified*/ static int nerrs = 0; /* number of errors during processing */ static int ngood = 0; /* number of good results */ static int lasterr = 0; /* value of the last error */ static char fCustomPEF = 0; /* =1 if -j to input a custom PEF record */ static char fSetPEFOks = 0; /* =1 if -k to set PEF OK rules */ static char fdisable = 0; static char fenable = 0; /* =1 to config BMC LAN and PEF */ static char fpefenable = 0; /* =1 enable PEF if Alert Dest is specified*/ static char fdisableSOL = 0; static char fgetser = 0; static char fsetifn = 0; /* =1 if user specified ifname[] with -i */ static char fethfound = 0; /* =1 if FindEthNum successful */ static char fset_ip = 0; /* !=0 if options used to specify an IP addr*/ static char fpassword = 0; /* =1 user-specified a password, so set it. */ static uchar fmBMC = 0; /* =1 mini-BMC, =0 Sahalee BMC */ static uchar fiBMC = 0; /* =1 Intel iBMC */ static uchar fRomley = 0; /* =1 Intel Romley BMC */ static uchar fipv6 = 0; /* =1 if BMC supports IPv6 */ static uchar bmcpefctl = 0; /* existing BMC PEF Control, !0 = enabled */ static char alertnum = 1; /* alert dest num (usu 1 thru 4) */ static char alertmax = 9; /* alert dest num max (usu 4, error if >9) */ static char pefnum = 12; /* 11 pre-defined entries, adding 12th */ static char pefadd = 0; /* num PEF rules added (usu 2, could be 5 */ static char pefmax = MAXPEF; /* 20 for Sahalee, 30 for miniBMC */ static char *myuser = NULL; /* username to set, specified by -u */ static uchar usernum = 0; /* set non-zero to specify user number */ static uchar rgmyip[4] = {0,0,0,0}; static uchar rggwyip[4] = {0,0,0,0}; static uchar rggwy2ip[4] = {0,0,0,0}; static uchar rgdestip[4] = {0,0,0,0}; static uchar rgsubnet[4] = {0,0,0,0}; static uchar bmcsubnet[4] = {255,255,255,0}; /* default subnet */ static uchar ossubnet[4] = {0,0,0,0}; static uchar osmyip[4] = {0,0,0,0}; static uchar bmcmyip[4] = {0,0,0,0}; static uchar bmcdestip[4] = {0,0,0,0}; static uchar bmcdestmac[6]= {0xff,0,0,0,0,0}; static uchar bmcmymac[6] = {0xff,0,0,0,0,0}; static uchar rgmymac[6] = {0xff,0,0,0,0,0}; static uchar osmymac[6] = {0xff,0,0,0,0,0}; static uchar rggwymac[6] = {0xff,0,0,0,0,0}; static uchar rggwy2mac[6] = {0xff,0,0,0,0,0}; static uchar rgdestmac[6] = {0xff,0,0,0,0,0}; static uchar rgdhcpmac[6] = {0xff,0,0,0,0,0}; static int nciphers = 16; static int ncipher0 = 0; static uchar rgciphers[16] = {0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; static char rghostname[32] = {'\0'}; static uchar custPEF[20]; /* max used = 18 bytes */ static char rgcommunity[19] = "public"; /* default community */ static char fsetcommunity = 0; /* =1 if user-specified community */ static char passwordData[PSW_MAX+1] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; static uchar authmask = 0; /* usu 0x17, mBMC = 0x15 */ static uchar bAuth = 0x16; /*exclude auth=None for security*/ static uchar lan_access = 0x04; /* usu 4=Admin, 3=Operator, 2=User */ static uchar lan_user = 0x02; /* if -u specified, use user 2 for lan */ static uchar arp_interval = 0x04; /* in 500 ms increments, 0-based */ static uchar arp_ctl = 0x01; /* 01=grat arp, 02=arp resp, 03=both*/ static uchar fsetarp = 0; /* 1=user-specified arp_ctl */ #ifdef WIN32 static uchar ostype = OS_WINDOWS; /*windows*/ static char ifname[64] = "Local Area Connection "; /* interface name */ static char ifpattn[25] = "Local Area Connection "; #elif SOLARIS /* for i86pc use "e1000g0", but for sun4u(sparc) this might be "eri0" */ static uchar ostype = OS_SOLARIS; #ifdef __SPARC__ static char ifname[16] = "eri0"; /* SPARC interface name */ static char ifname0[16] = "eri0"; static char ifpattn[14] = "eri"; #else static char ifname[16] = "e1000g0"; /* Solaris x86 interface name */ static char ifname0[16] = "e1000g0"; static char ifpattn[14] = "e1000g"; #endif #elif defined(BSD) static uchar ostype = OS_BSD; static char ifname[16] = "em0"; /* interface name */ static char ifname0[16] = "em0"; static char ifpattn[14] = "em"; #elif defined(HPUX) static uchar ostype = OS_HPUX; static char ifname[16] = "lan0"; /* interface name */ static char ifname0[16] = "lan0"; static char ifpattn[14] = "lan"; #else static uchar ostype = OS_LINUX; static char ifname[16] = "eth0"; /* interface name */ static char ifname0[16] = "eth0"; static char ifpattn[14] = "eth"; #endif static char *pspace1 = "\t"; /*used for fcanonical output*/ static char *pspace2 = "\t\t"; static char *pspace3 = "\t\t\t"; static char *pspace4 = "\t\t\t\t"; static int vend_id; static int prod_id; static int lan_dhcp = 0; /*=1 if using DHCP for bmc lan channel*/ static uchar ser_ch = SER_CH; static uchar lan_ch = LAN_CH; static uchar lan_ch_parm = PARM_INIT; static uchar gcm_ch = PARM_INIT; static uchar vlan_enable = PARM_INIT; static uchar failover_enable = PARM_INIT; static uchar vlan_prio = 0; /*default = 0*/ static ushort vlan_id = 0; /*max 12 bits used*/ static uchar max_users = 5; /* set in GetUser(1); */ static uchar enabled_users = 0; /* set in GetUser(1); */ static uchar show_users = 5; /* default, adjusted based on DeviceID */ static uchar fnewbaud = 0; /* =1 if user specified baud */ static uchar sol_baud = SOL_PREFERRED_BAUD_RATE; /*115.2k default*/ static uchar sol_accum[2] = { 0x04, 0x32 }; static uchar sol_retry[2] = { 0x06, 0x14 }; static uchar sol_bvalid = 0; /* =1 if SOL baud is valid */ static uchar chan_pefon = CHAN_ACC_PEFON; static uchar chan_pefoff = CHAN_ACC_PEFOFF; static uchar SessInfo[18]; /* Session Info data */ // static uchar bparm7[3] = {0x00, 0x00, 0x00}; /*ipv4 header before*/ static uchar iparm7[3] = {0x1E, 0x00, 0x00}; /*intel ipv4 TTL,Flags,Service*/ static uchar oparm7[3] = {0x40, 0x40, 0x10}; /*other ipv4 TTL,Flags,Service*/ static uchar *parm7 = &oparm7[0]; #define MAX_PEFPARAMS 14 /* max pef params = 14 */ uchar peflen[MAX_PEFPARAMS] = {0,1,1,1,1,1,21,2,1,4,17,1,3,18}; /*for ShowPef*/ uchar pef_array[MAXPEF][21]; /* array of all PEF entries read, */ /* sizeof(PEF_RECORD) = 21 */ uchar pef_defaults[11][21] = { /* array of first 11 default PEF entries */ {0x01,0x80,1,1,PEF_SEV_CRIT,0xff,0xff,0x01,0xff,0x01,0x95,0x0a,0,0,0,0,0,0,0,0,0}, /*Temp*/ {0x02,0x80,1,1,PEF_SEV_CRIT,0xff,0xff,0x02,0xff,0x01,0x95,0x0a,0,0,0,0,0,0,0,0,0}, /*Volt*/ {0x03,0x80,1,1,PEF_SEV_CRIT,0xff,0xff,0x04,0xff,0x01,0x95,0x0a,0,0,0,0,0,0,0,0,0}, /*Fan*/ {0x04,0x80,1,1,PEF_SEV_WARN,0xff,0xff,0x05,0x05,0x03,0x01,0x00,0,0,0,0,0,0,0,0,0}, /*Chass*/ {0x05,0x80,1,1,PEF_SEV_WARN,0xff,0xff,0x08,0xff,0x6f,0x06,0x00,0,0,0,0,0,0,0,0,0}, /*PS*/ {0x06,0x80,1,1,PEF_SEV_WARN,0xff,0xff,0x0c,0x08,0x6f,0x02,0x00,0,0,0,0,0,0,0,0,0}, /*ECC*/ {0x07,0x80,1,1,PEF_SEV_CRIT,0xff,0xff,0x0f,0x06,0x6f,0x01,0x00,0,0,0,0,0,0,0,0,0}, /*FRB*/ {0x08,0x80,1,1,PEF_SEV_WARN,0xff,0xff,0x07,0xff,0x6f,0x1c,0x00,0,0,0,0,0,0,0,0,0}, /*POST*/ {0x09,0x80,1,1,PEF_SEV_CRIT,0xff,0xff,0x13,0xff,0x6f,0x3e,0x03,0,0,0,0,0,0,0,0,0}, /*NMI*/ {0x0a,0x80,1,1,PEF_SEV_INFO,0xff,0xff,0x23,0x03,0x6f,0x0e,0x00,0,0,0,0,0,0,0,0,0}, /*WDT*/ {0x0b,0x80,1,1,PEF_SEV_MON,0xff,0xff,0x12,0xff,0x6f,0x02,0x00,0,0,0,0,0,0,0,0,0} };/*Restart*/ char **pefdesc; char *pefdesc1[MAXPEF] = { /* for Sahalee BMC */ /* 0 0x00 */ "", /* 1 0x01 */ "Temperature Sensor", /* 2 0x02 */ "Voltage Sensor", /* 3 0x04 */ "Fan Failure", /* 4 0x05 */ "Chassis Intrusion", /* 5 0x08 */ "Power Supply Fault", /* 6 0x0c */ "Memory ECC Error", /* 7 0x0f */ "BIOS POST Error", /* 8 0x07 */ "FRB Failure", /* 9 0x13 */ "Fatal NMI", /*10 0x23 */ "Watchdog Timer Reset", /*11 0x12 */ "System Restart", /*12 0x20 */ "OS Critical Stop", /*13 0x09 */ "Power Redundancy Lost", /*14 0x00 */ "reserved", /*15 0x00 */ "reserved", /*16 0x00 */ "reserved", /*17 */ "reserved", /*18 */ "reserved", /*19 */ "reserved", /*20 */ "reserved", /*21 */ "reserved", /*22 */ "reserved", /*23 */ "reserved", /*24 */ "reserved", /*25 */ "reserved", /*26 */ "reserved", /*27 */ "reserved", /*28 */ "reserved", /*29 */ "unused", /*30 */ "unused" }; char *pefdesc2[MAXPEF] = { /* for NSC miniBMC */ /* 0 */ "", /* 1 0x02*/ "Voltage Sensor Assert", /* 2 0x23*/ "Watchdog FRB Timeout", /* was "Proc FRB Thermal", */ /* 3 0x02*/ "Voltage Sensor Deassert", /* 4 0x07*/ "Proc1 IERR", /* 5 0xff*/ "Digital Sensor OK", /* 6 0x14*/ "Chassis Identify", /* 7 0x13*/ "NMI Button", /* 8 0x14*/ "Clear CMOS via Panel", /* 9 0x0f*/ "OS Load POST Code", /*10 0x20*/ "OS Critical Stop", /*11 0x09 */ "Power Redundancy Lost", /*12 0x00*/ "reserved", /*13 */ "reserved", /*14 */ "reserved", /*15 */ "reserved", /*16 */ "reserved", /*17 */ "reserved", /*18 */ "reserved", /*19 */ "reserved", /*20 */ "reserved", /*21 */ "reserved", /*22 */ "reserved", /*23 */ "reserved", /*24 */ "reserved", /*25 */ "reserved", /*26 0x05*/ "Chassis Intrusion", /*27 0x0f*/ "POST Code Error", /*28 0x02*/ "Voltage Failure", /*29 0x04*/ "Fan Failure", /*30 0x01*/ "Temperature Failure"}; #define NLAN 39 char canon_param[NLAN] = { 0,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,1,0,0,1, 0,0,0,0,0,0,1,1,1,1}; struct { int cmd; int sz; char desc[28]; } lanparams[NLAN] = { /* see IPMI Table 19-4 */ /* 0 */ { 0, 1, "Set in progress"}, /* 1 */ { 1, 1, "Auth type support"}, /* 2 */ { 2, 5, "Auth type enables"}, /* 3 */ { 3, 4, "IP address"}, /* 4 */ { 4, 1, "IP addr src"}, /* (DHCP/Static) */ /* 5 */ { 5, 6, "MAC addr"}, /* 6 */ { 6, 4, "Subnet mask"}, /* 7 */ { 7, 3, "IPv4 header"}, /* 8 */ { 8, 2, "Prim RMCP port"}, /* 9 */ { 9, 2, "Sec RMCP port"}, /* 10 */ {10, 1, "BMC grat ARP"}, /* 11 */ {11, 1, "grat ARP interval"}, /* 12 */ {12, 4, "Def gateway IP"}, /* 13 */ {13, 6, "Def gateway MAC"}, /* 14 */ {14, 4, "Sec gateway IP"}, /* 15 */ {15, 6, "Sec gateway MAC"}, /* 16 */ {16,18, "Community string"}, /* 17 */ {17, 1, "Num dest"}, /* 18 */ {18, 5, "Dest type"}, /* 19 */ {19, 13, "Dest address"}, /* 20 */ {20, 2, "VLAN ID"}, /* 21 */ {21, 1, "VLAN Priority"}, /* 22 */ {22, 1, "Cipher Suite Support"}, /* 23 */ {23,17, "Cipher Suites "}, /* 24 */ {24, 9, "Cipher Suite Priv"}, /* 25 */ {25, 4, "VLAN Dest Tag"}, /* 26 */ {96, 28, "OEM Alert String"}, /* 27 */ {97, 1, "Alert Retry Algorithm"}, /* 28 */ {98, 3, "UTC Offset"}, /* 29 */ {102, 1, "IPv6 Enable"}, /* 30 */ {103, 1, "IPv6 Addr Source"}, /* 31 */ {104,16, "IPv6 Address"}, /* 32 */ {105, 1, "IPv6 Prefix Len"}, /* 33 */ {106,16, "IPv6 Default Gateway"}, /* 34 */ {108,17, "IPv6 Dest address"}, /* 35 */ {192, 4, "DHCP Server IP"}, /* 36 */ {193, 6, "DHCP MAC Address"}, /* 37 */ {194, 1, "DHCP Enable"}, /* 38 */ {201, 2, "Channel Access Mode(Lan)"} }; #define NSER 22 /* max=32 */ struct { int cmd; int sz; char desc[28]; } serparams[NSER] = { /* see IPMI Table 20-4 */ /* 0 */ { 0, 1, "Set in progress"}, /* 1 */ { 1, 1, "Auth type support"}, /* 2 */ { 2, 5, "Auth type enables"}, /* 3 */ { 3, 1, "Connection Mode"}, /* 4 */ { 4, 1, "Sess Inactiv Timeout"}, /* 5 */ { 5, 5, "Channel Callback"}, /* 6 */ { 6, 1, "Session Termination"}, /* 7 */ { 7, 2, "IPMI Msg Comm"}, /* 8 */ { 8, 2, "Mux Switch"}, /* 9 */ { 9, 2, "Modem Ring Time"}, /* 10 */ {10,17, "Modem Init String"}, /* 11 */ {11, 5, "Modem Escape Seq"}, /* 12 */ {12, 8, "Modem Hangup Seq"}, /* 13 */ {13, 8, "Modem Dial Command"}, /* 14 */ {14, 1, "Page Blackout Interval"}, /* 15 */ {15,18, "Community String"}, /* 16 */ {16, 1, "Num of Alert Dest"}, /* 17 */ {17, 5, "Destination Info"}, /* 18 */ {18, 1, "Call Retry Interval"}, /* 19 */ {19, 3, "Destination Comm Settings"}, /* 20 */ {29, 2, "Terminal Mode Config"}, /* 21 */ {201, 2,"Channel Access Mode (Ser)"} }; static void getauthstr(uchar auth, char *s) { if (s == NULL) return; s[0] = 0; if (auth & 0x01) strcat(s,"None "); if (auth & 0x02) strcat(s,"MD2 "); if (auth & 0x04) strcat(s,"MD5 "); if (auth & 0x10) strcat(s,"Pswd "); if (auth & 0x20) strcat(s,"OEM "); return; } static int GetDeviceID(LAN_RECORD *pLanRecord) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; int status; uchar inputData[24]; uchar completionCode; if (pLanRecord == NULL) return(-1); status = ipmi_cmd(GET_DEVICE_ID, inputData, 0, responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { if( completionCode ) { SELprintf("GetDeviceID: completion code=%x\n", completionCode); status = completionCode; } else { memcpy(pLanRecord,&responseData[0],responseLength); set_mfgid(&responseData[0],responseLength); return(0); // successful, done } } /* endif */ /* if get here, error */ return(status); } /*end GetDeviceID() */ static int GetChanAcc(uchar chan, uchar parm, LAN_RECORD *pLanRecord) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; int status; uchar inputData[24]; uchar completionCode; if (pLanRecord == NULL) return(-1); responseLength = 3; inputData[0] = chan; inputData[1] = parm; /* 0x80 = active, 0x40 = non-volatile */ responseLength = sizeof(responseData); status = ipmi_cmd(GET_CHANNEL_ACC, inputData, 2, responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { if( completionCode ) { SELprintf("GetChanAcc: completion code=%x\n", completionCode); status = completionCode; } else { // dont copy first byte (Parameter revision, usu 0x11) memcpy(pLanRecord,&responseData[0],responseLength); return(0); // successful, done } } /* endif */ /* if get here, error */ return(status); } /*GetChanAcc()*/ static int SetChanAcc(uchar chan, uchar parm, uchar val) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; int status; uchar inputData[24]; uchar completionCode; if (fmBMC) return(0); /* mBMC doesn't support this */ /* parm: 0x80 = active, 0x40 = set non-vol*/ responseLength = 1; inputData[0] = chan; /* channel */ inputData[1] = (parm & 0xc0) | (val & 0x3F); inputData[2] = (parm & 0xc0) | lan_access; /* set priv level to Admin */ responseLength = sizeof(responseData); status = ipmi_cmd(SET_CHANNEL_ACC, inputData, 3, responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { if( completionCode ) { SELprintf("SetChanAcc: completion code=%x\n", completionCode); status = completionCode; } else { return(0); // successful, done } } /* endif */ /* if get here, error */ return(status); } /*SetChanAcc()*/ int SetPasswd(int unum, char *uname, char *upswd) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; int status, i, psw_len; uchar completionCode; char inputData[24]; int ret = 0; inputData[0] = (uchar)unum; /*user 1 = null user */ responseLength = sizeof(responseData); status = ipmi_cmd(GET_USER_NAME, inputData, 1, responseData, &responseLength, &completionCode, fdebug); SELprintf("GET_USERNAME: %x %x %x, status = %x, ccode=%x\n", responseData[0],responseData[1],responseData[2], status,completionCode); if (fdebug) { char aname[17]; printf("User %d: ",unum); for (i = 0; i < responseLength; i++) { printf("%02x ",responseData[i]); if (responseData[i] < 0x20) aname[i] = '.'; else aname[i] = responseData[i]; } aname[16] = 0; printf(" %s\n",aname); } if (unum != 1) { /* user specified a lan username */ if (fiBMC && (unum == 2)) { /* cannot set user 2 name */ if (uname != NULL) { if (strcmp(uname,"root") != 0) printf("SETUSERNAME - user2 name %s must be root\n",uname); } } else if (unum == 2 && (vend_id == VENDOR_SUPERMICROX || vend_id == VENDOR_SUPERMICRO) ) { /* cannot set user 2 name */ if (uname != NULL) { if (strcmp(uname,"ADMIN") != 0) printf("SETUSERNAME - user2 name %s must be ADMIN\n",uname); } } else { inputData[0] = (uchar)unum; memset(&inputData[1],0,16); if (uname != NULL) memcpy(&inputData[1],uname,strlen(uname)); status = ipmi_cmd(SET_USER_NAME, inputData, 17, responseData, &responseLength, &completionCode, fdebug); if (completionCode == 0xCC) status = 0; /*setting username to previous gives 0xCC, ok*/ else { SELprintf("SETUSERNAME - %x %x %x status = %x, ccode=%x\n", inputData[0],inputData[1],inputData[2], status,completionCode); if (status == 0) status = completionCode; if (status != 0) ret = status; } } } if ((unum != 1) && (uname == NULL)) { ; /* if no username, do not enable user */ } else { inputData[0] = (uchar)unum; inputData[1] = 0x01; /*enable user*/ responseLength = sizeof(responseData); status = ipmi_cmd(SET_USER_PASSWORD, inputData, 2, responseData, &responseLength, &completionCode, fdebug); printf("SETUSERENAB - inputData %x %x %x, status = %x, ccode=%x\n", inputData[0],inputData[1],inputData[2], status,completionCode); if (status == 0) status = completionCode; if (status != 0) ret = status; } inputData[0] = (uchar)unum; inputData[1] = 0x02; /*set password*/ psw_len = PSW_LEN; /*=16 change if 20-byte passwords supported */ memset(&inputData[2],0,psw_len); if (upswd != NULL) strcpy(&inputData[2],upswd); if (fdebug) { char apsw[PSW_MAX+1]; char c; printf("Pswd %d: ",unum); for (i = 0; i < psw_len; i++) { c = inputData[i+2]; printf("%02x ",(unsigned char)c); if (c < 0x20) apsw[i] = '.'; else apsw[i] = c; } apsw[psw_len] = 0; printf(" %s\n",apsw); } responseLength = sizeof(responseData); status = ipmi_cmd(SET_USER_PASSWORD, inputData, 2+psw_len, responseData,&responseLength, &completionCode,fdebug); SELprintf("SETUSERPSW - inputData %x %x %x, status = %x, ccode=%x\n", inputData[0],inputData[1],inputData[2], status,completionCode); if (status == 0) status = completionCode; if (status != 0) ret = status; inputData[0] = (uchar)unum; /*user 1 = null user */ inputData[1] = 0x03; /*test password*/ memset(&inputData[2],0,psw_len); if (upswd != NULL) strcpy(&inputData[2],upswd); responseLength = sizeof(responseData); status = ipmi_cmd(SET_USER_PASSWORD, inputData, 2+psw_len, responseData,&responseLength, &completionCode,fdebug); SELprintf("TESTUSERPSW - inputData %x %x %x, status = %x, ccode=%x\n", inputData[0],inputData[1],inputData[2], status,completionCode); if (fiBMC && (unum == 2)) { /*iBMC doesn't support this on user 2*/ if (fdebug) printf("skipping SETUSER_ACCESS on iBMC for user %d\n",unum); } else { inputData[0] = 0x90 | lan_ch; /* = 0x97 */ inputData[1] = (uchar)unum; /* user num */ inputData[2] = lan_access; /* usu admin */ inputData[3] = 0x00; /* User Session Limit, 0=not limited*/ responseLength = sizeof(responseData); status = ipmi_cmd(SET_USER_ACCESS, inputData, 4, responseData, &responseLength, &completionCode, fdebug); printf("SETUSER_ACCESS - inputData %x %x %x, status = %x ccode=%x\n", (uchar)inputData[0],inputData[1],inputData[2], status,completionCode); if (status == 0) status = completionCode; if (status != 0) ret = status; } return(ret); } /*end SetPswd()*/ int SetUser(int unum, char *uname, char *passwd) { int ret = 0; /* if the user specified a username or password, set it. */ if ((fpassword) || (uname != NULL)) { ret = SetPasswd(unum, uname,passwd); /*set username and password*/ } return(ret); } /*end SetUser()*/ int DisableUser(int unum) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; int status; uchar completionCode; char inputData[24]; inputData[0] = 0x80 | lan_ch; /* = 0x87, no IPMI */ inputData[1] = (uchar)unum; /* user 1 */ inputData[2] = 0x0F; /* No access */ inputData[3] = 0x00; /* User Session Limit, 0=not limited*/ responseLength = sizeof(responseData); status = ipmi_cmd(SET_USER_ACCESS, inputData, 4, responseData, &responseLength, &completionCode, fdebug); if (status == 0) status = completionCode; return(status); } static char *parse_priv(uchar c) { char *p; c = (c & 0x0f); switch(c) { case 1: p = "Callback"; break; case 2: p = "User "; break; case 3: p = "Operator"; break; case 4: p = "Admin "; break; case 5: p = "OEM "; break; case 0x0f: p = "No access"; break; default: p = "Reserved"; /*usually =0*/ } return(p); } static void show_priv(uchar c) { char *privstr; privstr = parse_priv(c); printf("%s",privstr); } static int valid_priv(int c) { int rv; switch(c) { case 1: case 2: case 3: case 4: case 5: case 0x0f: rv = 1; break; default: rv = 0; break; } return rv; } int GetUser(uchar user_num) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; int status; uchar completionCode; char inputData[24]; inputData[0] = lan_ch; inputData[1] = user_num; /* usually = 1 for BMC LAN */ responseLength = sizeof(responseData); status = ipmi_cmd(GET_USER_ACCESS, inputData, 2, responseData, &responseLength, &completionCode, fdebug); if (status == 0 && completionCode == 0) { uchar c; if (user_num == 1) { /*get max_users and enabled_users*/ max_users = responseData[0] & 0x3f; enabled_users = responseData[1] & 0x3f; if (enabled_users > show_users) show_users = enabled_users; if (show_users > max_users) show_users = max_users; if (!fcanonical) SELprintf("Users: showing %d of max %d users (%d enabled)\n", show_users,max_users,enabled_users); } if (fcanonical) SELprintf("Channel %d User %d Access %s%c ", lan_ch, user_num, pspace2,bdelim); else SELprintf("User Access(chan%d,user%d): %02x %02x %02x %02x : ", lan_ch, user_num, (uchar)responseData[0], responseData[1],responseData[2], responseData[3]); c = responseData[3]; inputData[0] = user_num; /* usually = 1 for BMC LAN */ responseLength = sizeof(responseData); status = ipmi_cmd(GET_USER_NAME, inputData, 1, responseData, &responseLength, &completionCode, fdebug); if (status != 0 || completionCode != 0) responseData[0] = 0; if (c & 0x10) printf("IPMI, "); show_priv(c); printf(" (%s)\n",responseData); /*show user name */ } else SELprintf("Get User Access(%d,%d), status=%x, ccode=%x\n", lan_ch, user_num, status, completionCode); return(status); } /*end GetUser()*/ static int GetSerEntry(uchar subfunc, LAN_RECORD *pLanRecord) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; uchar inputData[24]; int status; uchar completionCode; uchar chan; uchar bset; if (pLanRecord == NULL) { if (fdebug) printf("GetSerEntry(%d): error, output buffer is NULL\n",subfunc); return (-1); } chan = ser_ch; /* 1=EMP, 0=IPMB, 6=LAN2, 7=LAN1 */ bset = 0; inputData[0] = chan; // flags, channel 3:0 (1=EMP) inputData[1] = subfunc; // Param selector inputData[2] = bset; // Set selector inputData[3] = 0; // Block selector if (subfunc == 10) { inputData[2] = 0; inputData[3] = 1; } status = ipmi_cmd(GET_SER_CONFIG, inputData, 4, responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { if( completionCode ) { if (fdebug) SELprintf("GetSerEntry(%d,%d): completion code=%x\n", chan,subfunc,completionCode); } else { // dont copy first byte (Parameter revision, usu 0x11) memcpy(pLanRecord,&responseData[1],responseLength-1); pLanRecord->data[responseLength-1] = 0; //successful, done return(0); } } // we are here because completionCode is not COMPLETION_CODE_OK if (fdebug) SELprintf("GetSerEntry(%d,%d): ipmi_cmd status=%x ccode=%x\n", chan,subfunc,status,completionCode); return -1; } static int GetLanEntry(uchar subfunc, uchar bset, LAN_RECORD *pLanRecord) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; uchar inputData[24]; int status, n; uchar completionCode; uchar chan; if (pLanRecord == NULL) { if (fdebug) printf("GetLanEntry: error, output buffer is NULL\n"); return (-1); } chan = lan_ch; /* LAN 1 = 7 */ inputData[0] = chan; // flags, channel 3:0 (LAN 1) inputData[1] = subfunc; // Param selector (3 = ip addr) inputData[2] = bset; // Set selector inputData[3] = 0; // Block selector status = ipmi_cmd(GET_LAN_CONFIG, inputData, 4, responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { if( completionCode ) { if (fdebug) SELprintf("GetLanEntry: completion code=%x\n", completionCode); status = completionCode; } else { // dont copy first byte (Parameter revision, usu 0x11) if (responseLength > 0) { n = responseLength-1; memcpy(pLanRecord,&responseData[1],n); } else n = 0; pLanRecord->data[n] = 0; //successful, done return(0); } } // we are here because completionCode is not COMPLETION_CODE_OK if (fdebug) SELprintf("GetLanEntry: ipmi_cmd status=%d completionCode=%x\n", status,completionCode); return status; } /* end GetLanEntry() */ static int SetLanEntry(uchar subfunc, LAN_RECORD *pLanRecord, int reqlen) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; uchar inputData[24]; int status; uchar completionCode; if (pLanRecord == NULL) { if (fdebug) printf("SetLanEntry(%d): error, input buffer is NULL\n",subfunc); return (-1); } if (vend_id == VENDOR_SUPERMICROX || vend_id == VENDOR_SUPERMICRO) { /* SUPERMICRO cannot set grat arp or grat arp interval */ if (subfunc == 10 || subfunc == 11) return(0); } inputData[0] = lan_ch; // flags, channel 3:0 (LAN 1) inputData[1] = subfunc; // Param selector (3 = ip addr) memcpy(&inputData[2],pLanRecord,reqlen); status = ipmi_cmd(SET_LAN_CONFIG, inputData, (uchar)(reqlen+2), responseData, &responseLength,&completionCode,fdebug); if (status == ACCESS_OK) { if( completionCode ) { if (fdebug) SELprintf("SetLanEntry(%d): completion code=%x\n", subfunc,completionCode); // responseData[0]); return(completionCode); } else { //successful, done return(0); } } // we are here because completionCode is not COMPLETION_CODE_OK if (fdebug) SELprintf("SetLanEntry(%d): ipmi_cmd status=%d ccode=%x\n", subfunc,status,completionCode); return status; } /* end SetLanEntry() */ int GetPefEntry(uchar subfunc, ushort rec_id, PEF_RECORD *pPefRecord) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; uchar inputData[24]; /* only use 3 bytes for input */ int status, n; uchar completionCode; if (pPefRecord == NULL) { if (fdebug) printf("GetPefEntry(%d): error, output buffer is NULL\n",subfunc); return (-1); } inputData[0] = subfunc; // Parameter = Evt Filter Table inputData[1] = (uchar)rec_id; inputData[2] = 0; status = ipmi_cmd(GET_PEF_CONFIG, inputData, 3, responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { if( completionCode ) { if (fdebug) SELprintf("GetPefEntry(%d/%d): completion code=%x\n", subfunc,rec_id,completionCode); status = completionCode; } else { /* expect PEF record to be >=21 bytes */ if (responseLength > 1) n = responseLength-1; else n = 0; if (n > 21) n = 21; /*only use 21 bytes*/ if ((subfunc == 6) && (n < 21)) { if (fdebug) printf("GetPefEntry(%d/%d): length %d too short\n", subfunc,rec_id,responseLength); } // dont copy first byte (Parameter revision, usu 0x11) if (n == 0) memset(pPefRecord,0,21); else memcpy(pPefRecord,&responseData[1],n); //successful, done return(0); } } // we are here because completionCode is not COMPLETION_CODE_OK if (fdebug) SELprintf("GetPefEntry: ipmi_cmd status=%x completionCode=%x\n", status, completionCode); return status; } /* end GetPefEntry() */ int SetPefEntry(PEF_RECORD *pPefRecord) { uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; uchar inputData[32]; /* sizeof(PEF_RECORD) = 21 +1=22 */ int status; uchar completionCode; uchar subfunc; subfunc = 0x06; // Parameter = Evt Filter Table if (pPefRecord == NULL) { if (fdebug) printf("SetPefEntry: error, output buffer is NULL\n"); return (-1); } // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // 06 0c 80 01 01 00 ff ff 20 ff 6f ff 00 00 00 00 00 00 00 00 00 00 // memset(&inputData[0],0,requestData.dataLength); inputData[0] = subfunc; memcpy(&inputData[1],pPefRecord,sizeof(PEF_RECORD)); status = ipmi_cmd(SET_PEF_CONFIG, inputData, sizeof(PEF_RECORD)+1, responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { if( completionCode ) { if (fdebug) SELprintf("SetPefEntry: completion code=%x\n", completionCode); // responseData[0]); status = completionCode; } else { //successful, done return(0); } } // we are here because completionCode is not COMPLETION_CODE_OK if (fdebug) SELprintf("SetPefEntry: ipmi_cmd status=%d completion code=%x\n", status,completionCode); return(status); } /* end SetPefEntry() */ int DisablePef(int anum) { uchar iData[24]; /* sizeof(PEF_RECORD) = 21 +1=22 */ uchar rData[MAX_BUFFER_SIZE]; int rLength = MAX_BUFFER_SIZE; uchar cc; int status; if (fmBMC) { SELprintf("mini-BMC does not support disabling BMC LAN\n"); return(-1); } else { status = SetChanAcc(lan_ch, 0x80, CHAN_ACC_DISABLE); if (fdebug) SELprintf("SetChanAcc(lan/active), ret = %d\n",status); status = SetChanAcc(lan_ch, 0x40, CHAN_ACC_DISABLE); SELprintf("SetChanAcc(lan), ret = %d\n",status); if (status != 0) return(status); } iData[0] = 0x01; /* PEF Control Param */ iData[1] = 0x00; /* PEF disable */ rLength = MAX_BUFFER_SIZE; status = ipmi_cmd(SET_PEF_CONFIG, iData, 2, rData, &rLength, &cc, fdebug); if (status != 0) return(status); if( cc ) { SELprintf("DisablePef[%d]: completion code=%x\n",iData[0],cc); return(-1); } if (anum != 0) { iData[0] = 0x09; /* PEF Alert Policy Table */ iData[1] = (uchar)anum; /* Policy number (default 0x01) */ iData[2] = 0x10; /* PEF LAN, policy disable */ iData[3] = 0x00; /* LAN_CH=00, default dest=00 */ iData[4] = 0x00; /* No alert string */ rLength = MAX_BUFFER_SIZE; status = ipmi_cmd(SET_PEF_CONFIG, iData, 5, rData, &rLength, &cc, fdebug); if (status != 0) return(status); if( cc ) { SELprintf("DisablePef[%d]: completion code=%x\n",iData[0],cc); return(-1); } } return(status); } int ShowPef(void) { uchar iData[24]; /* sizeof(PEF_RECORD) = 21 +1=22 */ uchar rData[MAX_BUFFER_SIZE]; int rLength = MAX_BUFFER_SIZE; uchar cc; int status, i,j; for (j = 1; j < MAX_PEFPARAMS; j++) { if (j == 4 && fmBMC) { /* fmBMC gets cc=0x80 for param 4, so skip it. */ continue; } iData[0] = (uchar)j; /* PEF Control Param */ if (j == 6 || j == 7 || j == 9) iData[1] = 1; else iData[1] = 0x00; /* PEF Set Selector */ if (j == 13) iData[2] = 1; else iData[2] = 0x00; /* PEF Block Selector */ rLength = MAX_BUFFER_SIZE; status = ipmi_cmd(GET_PEF_CONFIG, iData, 3, rData, &rLength, &cc, fdebug); if (status == 0 && cc == 0) { SELprintf("PefParam[%d]: ",iData[0]); if (rLength > 0) for (i=0;i= 'a' && str[i] <= 'z') str[i] &= 0x5F; for (i = 0; i < NBAUDS; i++) { n = strlen_(mapbaud[i].str); if (strncmp(str,mapbaud[i].str,n) == 0) { baud = mapbaud[i].val; break; } } if (i == NBAUDS || baud == 0) { printf("Invalid -B parameter value (%s), using 19.2K.\n",str); i = 1; /* default is 19.2K */ baud = mapbaud[i].val; /* =7 */ } if (fdebug) printf("new baud = %02x (%s)\n",baud,mapbaud[i].str); return(baud); } static char *Baud2Str(unsigned char bin) { char *baudstr; unsigned char b; b = bin & 0x0f; switch(b) { case 6: baudstr = "9600 "; break; case 7: baudstr = "19.2k"; break; case 8: baudstr = "38.4k"; break; case 9: baudstr = "57.6k"; break; case 10: baudstr = "115.2k"; break; default: baudstr = "nobaud"; } return(baudstr); } static int BaudValid(unsigned char b) { int val = 0; switch(b) { case 6: val = 1; break; case 7: val = 1; break; case 8: val = 1; break; case 9: val = 1; break; case 10: val = 1; break; default: val = 0; break; } return(val); } /* * atomac - converts ASCII string to binary MAC address (array). * Accepts input formatted as 11:22:33:44:55:66 or 11-22-33-44-55-66. */ void atomac(uchar *array, char *instr) { int i,j,n; char *pi; j = 0; pi = instr; n = strlen_(instr); for (i = 0; i <= n; i++) { if (instr[i] == ':') { array[j++] = htoi(pi); pi = &instr[i+1]; } else if (instr[i] == '-') { array[j++] = htoi(pi); pi = &instr[i+1]; } else if (instr[i] == 0) { array[j++] = htoi(pi); } if (j >= MAC_LEN) break; /*safety valve*/ } if (fdebug) printf("atomac: %02x %02x %02x %02x %02x %02x\n", array[0],array[1],array[2],array[3], array[4],array[5]); } /*end atomac()*/ /* extern void atoip(uchar *array,char *instr); *from subs.c*/ void MacSetInvalid(uchar *mac) { int i; if (mac == NULL) return; for (i = 0; i < MAC_LEN; i++) { if (i == 0) mac[i] = 0xFF; else mac[i] = 0x00; } } int MacIsValid(uchar *mac) { int fvalid = 0; int i; /* check for initial invalid value of FF:00:... */ if (mac[0] == 0xff && mac[1] == 0x00) /* marked as invalid */ return(fvalid); /* check for all zeros */ for (i = 0; i < MAC_LEN; i++) if (mac[i] != 0) { /* not all zeros */ fvalid = 1; break; } return(fvalid); } int IpIsValid(uchar *ipadr) { int fvalid = 1; if (ipadr[0] == 0) fvalid = 0; return(fvalid); } int SubnetIsValid(uchar *subnet) { int fvalid = 0; /* if masking off at least one bit, say valid */ if (subnet[0] != 0) fvalid = 1; return(fvalid); } int SubnetIsSame(uchar *ip1, uchar *ip2, uchar *subnet) { int i; uchar c1, c2; for (i = 0; i < 4; i ++) { c1 = ip1[i] & subnet[i]; c2 = ip2[i] & subnet[i]; if (c1 != c2) return 0; } return 1; /*same, return true*/ } #ifdef WIN32 /* * Obtain network adapter information (Windows). */ PIP_ADAPTER_ADDRESSES GetAdapters() { PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL; ULONG OutBufferLength = 0; ULONG RetVal = 0, i; // The size of the buffer can be different // between consecutive API calls. // In most cases, i < 2 is sufficient; // One call to get the size and one call to get the actual parameters. // But if one more interface is added or addresses are added, // the call again fails with BUFFER_OVERFLOW. // So the number is picked slightly greater than 2. // We use i <5 in the example for (i = 0; i < 5; i++) { RetVal = GetAdaptersAddresses( AF_INET, 0, NULL, AdapterAddresses, &OutBufferLength); if (RetVal != ERROR_BUFFER_OVERFLOW) { break; } if (AdapterAddresses != NULL) { free(AdapterAddresses); } AdapterAddresses = (PIP_ADAPTER_ADDRESSES) malloc(OutBufferLength); if (AdapterAddresses == NULL) { RetVal = GetLastError(); break; } } if (RetVal == NO_ERROR) { // If successful, return pointer to structure return AdapterAddresses; } else { LPVOID MsgBuf; printf("Call to GetAdaptersAddresses failed.\n"); if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, RetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &MsgBuf, 0, NULL )) { printf("\tError: %s", MsgBuf); } LocalFree(MsgBuf); } return NULL; } /* * Set BMC MAC corresponding to current BMC IP address (Windows). */ int GetLocalMACByIP() { PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL; PIP_ADAPTER_ADDRESSES AdapterList; int result = 0; struct sockaddr_in *si; AdapterAddresses = GetAdapters(); AdapterList = AdapterAddresses; while (AdapterList) { PIP_ADAPTER_UNICAST_ADDRESS addr; addr = AdapterList->FirstUnicastAddress; if (addr == NULL) si = NULL; else si = (struct sockaddr_in*)addr->Address.lpSockaddr; if (si != NULL) { if(memcmp(&si->sin_addr.s_addr, rgmyip, 4) == 0) { if (!MacIsValid(rgmymac)) memcpy(rgmymac, AdapterList->PhysicalAddress, MAC_LEN); memcpy(osmyip, &si->sin_addr.s_addr, 4); memcpy(osmymac, AdapterList->PhysicalAddress, MAC_LEN); wcstombs(ifname,AdapterList->FriendlyName, sizeof(ifname)); result = 1; break; } } AdapterList = AdapterList->Next; } if (AdapterAddresses != NULL) { free(AdapterAddresses); } return result; } /* * Get First IP Address in Windows OS * ipaddr is 4 bytes, macaddr is 6 bytes, ipname can be 64 bytes. * (called by idiscover.c) */ int GetFirstIP(uchar *ipaddr, uchar *macadr, char *ipname, char fdbg) { PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL; PIP_ADAPTER_ADDRESSES AdapterList; struct sockaddr_in *si; uchar *psaddr; int result = -1; AdapterAddresses = GetAdapters(); AdapterList = AdapterAddresses; while (AdapterList) { PIP_ADAPTER_UNICAST_ADDRESS addr; addr = AdapterList->FirstUnicastAddress; si = (struct sockaddr_in*)addr->Address.lpSockaddr; psaddr = (uchar *)&si->sin_addr.s_addr; if ((psaddr[0] != 0) && (psaddr[0] != 169)) { if (fdbg) printf("found IP: s_addr=%d.%d.%d.%d\n", psaddr[0], psaddr[1], psaddr[2], psaddr[3]); if (ipaddr != NULL) memcpy(ipaddr, &si->sin_addr.s_addr, 4); if (macadr != NULL) { memcpy(macadr, AdapterList->PhysicalAddress, MAC_LEN); if (fdbg) printf("found MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", macadr[0], macadr[1], macadr[2], macadr[3], macadr[4], macadr[5]); } if (ipname != NULL) { wcstombs(ipname,AdapterList->FriendlyName, sizeof(ifname)); if (fdbg) printf("found Adapter: %d\n",ipname); } result = 0; break; } AdapterList = AdapterList->Next; } if (AdapterAddresses != NULL) { free(AdapterAddresses); } return result; } /* * Set BMC MAC corresponding to current BMC IP address (Windows). */ int GetLocalIPByMAC(uchar *macadr) { PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL; PIP_ADAPTER_ADDRESSES AdapterList; int result = 0; struct sockaddr_in *si; AdapterAddresses = GetAdapters(); AdapterList = AdapterAddresses; while (AdapterList) { PIP_ADAPTER_UNICAST_ADDRESS addr; if(memcmp(AdapterList->PhysicalAddress, macadr, MAC_LEN) == 0) { addr = AdapterList->FirstUnicastAddress; si = (struct sockaddr_in*)addr->Address.lpSockaddr; if (fdebug) { uchar *psaddr; psaddr = (uchar *)&si->sin_addr.s_addr; printf("mac match: rgmyip=%d.%d.%d.%d s_addr=%d.%d.%d.%d\n", rgmyip[0], rgmyip[1], rgmyip[2], rgmyip[3], psaddr[0], psaddr[1], psaddr[2], psaddr[3]); } if (!IpIsValid(rgmyip) && (fsharedMAC==1)) /*not specified, shared*/ memcpy(rgmyip, &si->sin_addr.s_addr, 4); memcpy(osmyip, &si->sin_addr.s_addr, 4); memcpy(osmymac, AdapterList->PhysicalAddress, MAC_LEN); wcstombs(ifname,AdapterList->FriendlyName, sizeof(ifname)); result = 1; break; } AdapterList = AdapterList->Next; } if (AdapterAddresses != NULL) { free(AdapterAddresses); } return result; } /* * Set MAC and IP address from given interface name (Windows). */ int GetLocalDataByIface() { PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL; PIP_ADAPTER_ADDRESSES AdapterList; int result = 0; size_t origsize, newsize, convertedChars; wchar_t* wcstring; struct sockaddr_in *si; AdapterAddresses = GetAdapters(); AdapterList = AdapterAddresses; origsize = strlen(ifname) + 1; newsize = origsize; convertedChars = 0; wcstring = (wchar_t*) malloc(sizeof(wchar_t) * newsize) ; if (wcstring == NULL) AdapterList = NULL; /*skip loop, do free*/ else mbstowcs(wcstring, ifname, origsize ); while (AdapterList) { PIP_ADAPTER_UNICAST_ADDRESS addr; if(wcsstr(AdapterList->FriendlyName, wcstring)) { printf("Using interface: %S\n", AdapterList->FriendlyName); printf("\t%S\n", AdapterList->Description); addr = AdapterList->FirstUnicastAddress; si = (struct sockaddr_in*)addr->Address.lpSockaddr; if (fdebug) { uchar *psaddr; psaddr = (uchar *)&si->sin_addr.s_addr; printf("mac match: rgmyip=%d.%d.%d.%d s_addr=%d.%d.%d.%d " "fsharedMAC=%d\n", rgmyip[0], rgmyip[1], rgmyip[2], rgmyip[3], psaddr[0], psaddr[1], psaddr[2], psaddr[3], fsharedMAC); } if (!IpIsValid(rgmyip)) { /*IP not specified*/ memcpy(rgmyip, &si->sin_addr.s_addr, 4); memcpy(rgmymac, AdapterList->PhysicalAddress, MAC_LEN); } memcpy(osmyip, &si->sin_addr.s_addr, 4); memcpy(osmymac, AdapterList->PhysicalAddress, MAC_LEN); /* FriendlyName == ifname already */ result = 1; break; } AdapterList = AdapterList->Next; } if (AdapterAddresses != NULL) { free(AdapterAddresses); } return result; } int FindEthNum(uchar *macadrin) { int i; uchar macadr[MAC_LEN]; memcpy(macadr,macadrin,MAC_LEN); if (fsharedMAC == 0 && vend_id == VENDOR_INTEL) { /* Intel factory assigns them this way, so use that to compare */ macadr[MAC_LEN-1] -= 2; /*OS MAC = BMC MAC - 2*/ } i = GetLocalIPByMAC(macadr); if (i == 1) fethfound = 1; if (fdebug) /* show the local OS eth if and MAC */ printf("FindEth: OS %s IP=%d.%d.%d.%d MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", ifname, osmyip[0], osmyip[1], osmyip[2], osmyip[3], osmymac[0], osmymac[1], osmymac[2], osmymac[3], osmymac[4], osmymac[5]); /* The actual Windows ethernet interface is determined * in Get_IPMac_Addr using ipconfig, so * init eth interface number as eth0 for Windows. */ return(0); } #elif defined(HPUX) #define INSAP 22 #define OUTSAP 24 #include #include #include #include #include #include #include #include #include #include #define bcopy(source, destination, length) memcpy(destination, source, length) #define AREA_SZ 5000 /*=* buffer length in bytes *=*/ #define GOT_CTRL 1 #define GOT_DATA 2 #define GOT_BOTH 3 #define GOT_INTR 4 #define GOT_ERR 128 static u_long ctl_area[AREA_SZ]; static u_long dat_area[AREA_SZ]; static struct strbuf ctl = {AREA_SZ, 0, (char *)ctl_area}; static struct strbuf dat = {AREA_SZ, 0, (char *)dat_area}; static char *dlpi_dev[] = {"/dev/dlpi", ""}; /*=* get a message from a stream; return type of message *=*/ static int get_msg(int fd) { int flags = 0; int res, ret; ctl_area[0] = 0; dat_area[0] = 0; ret = 0; res = getmsg(fd, &ctl, &dat, &flags); if(res < 0) { if(errno == EINTR) { return(GOT_INTR); } else { return(GOT_ERR); } } if(ctl.len > 0) { ret |= GOT_CTRL; } if(dat.len > 0) { ret |= GOT_DATA; } return(ret); } /*=* verify that dl_primitive in ctl_area = prim *=*/ static int check_ctrl(int prim) { dl_error_ack_t *err_ack = (dl_error_ack_t *)ctl_area; if(err_ack->dl_primitive != prim) { return GOT_ERR; } return 0; } /*=* put a control message on a stream *=*/ static int put_ctrl(int fd, int len, int pri) { ctl.len = len; if(putmsg(fd, &ctl, 0, pri) < 0) { return GOT_ERR; } return 0; } /*=* put a control + data message on a stream *=*/ static int put_both(int fd, int clen, int dlen, int pri) { ctl.len = clen; dat.len = dlen; if(putmsg(fd, &ctl, &dat, pri) < 0) { return GOT_ERR; } return 0; } /*=* open file descriptor and attach *=*/ static int dl_open(const char *dev, int ppa, int *fd) { dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area; if((*fd = open(dev, O_RDWR)) == -1) { return GOT_ERR; } attach_req->dl_primitive = DL_ATTACH_REQ; attach_req->dl_ppa = ppa; put_ctrl(*fd, sizeof(dl_attach_req_t), 0); get_msg(*fd); return check_ctrl(DL_OK_ACK); } /*=* send DL_BIND_REQ *=*/ static int dl_bind(int fd, int sap, u_char *addr) { dl_bind_req_t *bind_req = (dl_bind_req_t *)ctl_area; dl_bind_ack_t *bind_ack = (dl_bind_ack_t *)ctl_area; bind_req->dl_primitive = DL_BIND_REQ; bind_req->dl_sap = sap; bind_req->dl_max_conind = 1; bind_req->dl_service_mode = DL_CLDLS; bind_req->dl_conn_mgmt = 0; bind_req->dl_xidtest_flg = 0; put_ctrl(fd, sizeof(dl_bind_req_t), 0); get_msg(fd); if (GOT_ERR == check_ctrl(DL_BIND_ACK)) { return GOT_ERR; } bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, bind_ack->dl_addr_length); return 0; } int FindEthNum(uchar *addr) { /* Need to use DLPI for HPUX */ /*See http://cplus.kompf.de/artikel/macaddr.html */ int fd; int ppa; u_char mac_addr[25]; char **dev; int i = 0; for (dev = dlpi_dev; **dev != ''; ++dev) { for (ppa=0; ppa<10; ++ppa) { if (GOT_ERR != dl_open(*dev, ppa, &fd)) { if (GOT_ERR != dl_bind(fd, INSAP, mac_addr)) { // bcopy( mac_addr, addr, 6); i = ppa; if (memcmp(mac_addr,addr,MAC_LEN) == 0) { memcpy(osmymac, addr, MAC_LEN); return(ppa); } } } close(fd); } } return(i); } #else static char *get_ifreq_mac(struct ifreq *ifrq) { char *ptr; #ifdef SOLARIS ptr = (char *)&ifrq->ifr_ifru.ifru_enaddr[0]; #elif BSD ptr = (char *)&ifrq->ifr_ifru.ifru_addr.sa_data[0]; #elif MACOS static uchar mactmp[MAC_LEN]; ptr = &mactmp[0]; MacSetInvalid(ptr); #else ptr = (char *)&ifrq->ifr_hwaddr.sa_data[0]; #endif return (ptr); } extern int find_ifname(char *ifname); /*see idiscover.c*/ int FindEthNum(uchar *macadrin) { /*only used for Linux*/ struct ifreq ifr; int skfd; int nCurDevice; int devnum = -1; int devos = 0; uchar macadr[MAC_LEN]; uchar macsav[MAC_LEN]; uchar mactmp[MAC_LEN]; uchar ipsav[4]; char szDeviceName[ 16 ]; /* MAX_DEVICE_NAME_LENGTH + 1 */ uchar fipvalid = 0; int n; memcpy(macadr,macadrin,MAC_LEN); if (fsharedMAC == 0 && vend_id == VENDOR_INTEL) { /* Intel factory assigns them this way, so use that to compare */ macadr[MAC_LEN-1] -= 2; /*OS MAC = BMC MAC - 2*/ } #ifdef DBG if (fdebug) { uchar *pb; pb = macadrin; printf("input mac:%02x:%02x:%02x:%02x:%02x:%02x " "tmp mac:%02x:%02x:%02x:%02x:%02x:%02x\n", pb[0],pb[1],pb[2],pb[3],pb[4],pb[5], macadr[0],macadr[1],macadr[2],macadr[3],macadr[4],macadr[5]); } #endif n = find_ifname(szDeviceName); if (n >= 0) { n = strlen_(szDeviceName); if (n < sizeof(ifpattn)) { strcpy(ifpattn,szDeviceName); ifpattn[n - 1] = 0; /*truncate last digit*/ } if (fdebug) printf("found ifname %s, pattern %s\n",szDeviceName,ifpattn); } if ( ( skfd = socket(AF_INET, SOCK_DGRAM, 0 ) ) < 0) { if ( fdebug ) { perror("socket"); return devnum; } } for( nCurDevice = 0 ; (nCurDevice < NUM_DEVICES_TO_CHECK) && (devnum == -1); nCurDevice++ ) { sprintf( szDeviceName, "%s%d", ifpattn, nCurDevice ); /*eth%d*/ memset((char *)&ifr,0,sizeof(ifr)); strcpy(ifr.ifr_name, szDeviceName ); #ifdef SIOCGIFHWADDR if (ioctl(skfd, SIOCGIFHWADDR, &ifr) > 0) { if ( fdebug ) printf("FindEthNum: Could not get MAC address for %s\n", szDeviceName); } else #endif { uchar *pb; pb = get_ifreq_mac(&ifr); #ifdef DBG if (fdebug) { printf("%s mac: %02x:%02x:%02x:%02x:%02x:%02x\n", szDeviceName, pb[0],pb[1],pb[2],pb[3],pb[4],pb[5]); } #endif memcpy(macsav, pb, MAC_LEN); /* check if this device is configured for IP addr */ memset((char *)&ifr,0,sizeof(ifr)); strcpy(ifr.ifr_name, szDeviceName); ifr.ifr_addr.sa_family = AF_INET; if (ioctl(skfd, SIOCGIFADDR, &ifr) >= 0) { fipvalid = 1; memcpy(ipsav, &ifr.ifr_addr.sa_data[2], 4); } else fipvalid = 0; if (memcmp(macsav, macadr, MAC_LEN) == 0) { /*found match*/ devnum = nCurDevice; memcpy(osmymac, macsav, MAC_LEN); if (fipvalid) memcpy(osmyip, ipsav, 4); break; } if (nCurDevice == 0) { /*set a default of eth0*/ devos = nCurDevice; memcpy(osmymac,macsav, MAC_LEN); if (fipvalid) memcpy(osmyip, ipsav, 4); } else if (fipvalid) { /*check if NIC1 is eth1,2,3,...*/ memcpy(mactmp,osmymac,MAC_LEN); mactmp[MAC_LEN-1] -= 1; if (memcmp(mactmp,macsav,MAC_LEN) == 0) { devos = nCurDevice; memcpy(osmymac, macsav, MAC_LEN); memcpy(osmyip, ipsav, 4); } } } /*end else*/ } if (!fsetifn) { if (devnum == -1) { /*not found, use devos default*/ devnum = devos; sprintf( ifname, "%s%d", ifpattn, devnum ); /*eth%d*/ } else { /* match was found, devnum set */ fethfound = 1; strcpy(ifname, szDeviceName ); } } close(skfd); if (fdebug) /* show the local OS eth if and MAC */ printf("FindEth: OS %s IP=%d.%d.%d.%d MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", ifname, osmyip[0], osmyip[1], osmyip[2], osmyip[3], osmymac[0], osmymac[1], osmymac[2], osmymac[3], osmymac[4], osmymac[5]); return(devnum); } #endif int show_channels(void) { int ret, rlen; uchar iData[2]; uchar rData[10]; uchar cc, mtype; int j; int rv = -1; for (j = 1; j < MAXCHAN; j++) { rlen = sizeof(rData); iData[0] = (uchar)j; /*channel #*/ memset(rData,0,9); /*initialize recv data*/ ret = ipmi_cmd(GET_CHANNEL_INFO, iData, 1, rData, &rlen, &cc, fdebug); if (rv != 0) rv = ret; if (ret == 0xcc || cc == 0xcc) /* special case for ipmi_lan */ continue; if (ret != 0) { if (fdebug) printf("get_chan_info rc = %x\n",ret); break; } mtype = rData[1]; /* channel medium type */ switch(mtype) { case 4: printf("channel[%d] type = lan\n",j); break; /*802.3 LAN type*/ case 5: printf("channel[%d] type = serial\n",j); break; case 7: printf("channel[%d] type = pci_smbus\n",j); break; case 12: printf("channel[%d] type = system_interface\n",j); break; default: printf("channel[%d] type = other %d\n",j,mtype); break; } rv = 0; } /*end for j*/ return(rv); } /* * GetBmcEthDevice * Attempt to auto-detect the BMC LAN channel and matching OS eth port. * INPUT: lan_parm = lan channel from user -L option, 0xFF if not specified * OUTPUT: lan_ch is set to BMC LAN channel number * if success, returns index of OS eth port (0, 1, ...). * if no lan channels found, returns -2. * if other error, returns -1. */ int GetBmcEthDevice(uchar lan_parm) { LAN_RECORD LanRecord; int devnum = -1; int ret; uchar bmcMacAddress[ MAC_LEN ]; /*MAC_LEN = 6*/ int rlen; uchar iData[2]; uchar rData[10]; uchar cc; int i = 0; int j, jstart, jend, jlan; uchar mtype; uchar *pb; int fchgmac; // int found = 0; /* Find the LAN channel(s) via Channel Info */ if (lan_parm < MAXCHAN) { /* try user-specified channel only */ lan_ch = lan_parm; jstart = lan_parm; jend = lan_parm+1; } else { jstart = 1; jend = MAXCHAN; } memset(bmcMacAddress,0xff,sizeof(bmcMacAddress)); /*initialize to invalid*/ for (j = jstart; j < jend; j++) { rlen = sizeof(rData); iData[0] = (uchar)j; /*channel #*/ memset(rData,0,9); /*initialize recv data*/ ret = ipmi_cmd(GET_CHANNEL_INFO, iData, 1, rData, &rlen, &cc, fdebug); if (ret == 0xcc || cc == 0xcc) /* special case for ipmi_lan */ continue; if (ret != 0) { if (fdebug) printf("get_chan_info rc = %x\n",ret); break; } mtype = rData[1]; /* channel medium type */ if (mtype == 4) { /* 802.3 LAN type*/ if (fdebug) printf("chan[%d] = lan\n",j); jlan = lan_ch; /*save prev lan chan */ /* Get BMC MAC for this LAN channel. */ /* Note: BMC MAC may not be valid yet. */ lan_ch = (uchar)j; /*set lan channel for GetLanEntry*/ ret = GetLanEntry( 5 /*MAC_ADDRESS_LAN_PARAM*/,0, &LanRecord); if ( ret != 0 ) { lan_ch = (uchar)jlan; /*restore lan_ch*/ printf( "GetBmcEthDevice: GetLanEntry failed\n" ); return devnum; } else { pb = &LanRecord.data[0]; if (fdebug) printf("chan[%d] BMC MAC %x:%x:%x:%x:%x:%x\n",j, pb[0], pb[1], pb[2], pb[3], pb[4], pb[5] ); fchgmac = 0; /* use the lowest valid lan channel MAC address */ if (!MacIsValid(bmcMacAddress)) /* old MAC not valid*/ fchgmac = 1; else if (MacIsValid(pb) && /* new MAC is valid and*/ (memcmp(bmcMacAddress,pb, sizeof(bmcMacAddress)) > 0)) fchgmac = 1; /* new MAC lower */ /* if no -L 3 and this is gcm, do not pick it. */ if ((j == gcm_ch) && (lan_parm == PARM_INIT)) fchgmac = 0; if (fchgmac) { /* pick this channel & MAC */ memcpy(bmcMacAddress,pb,sizeof(bmcMacAddress)); lan_ch = (uchar)j; } else lan_ch = (uchar)jlan; /*restore prev lan chan*/ } i++; /* i = num lan channels found */ } else if (mtype == 5) { /* serial type*/ if (fdebug) printf("chan[%d] = serial\n",j); ser_ch = (uchar)j; /* set to last serial channel */ } else if (mtype == 7) { /* PCI SMBus */ if (fdebug) printf("chan[%d] = pci_smbus\n",j); } else if (mtype == 12) { /* system interface */ if (fdebug) printf("chan[%d] = system_interface\n",j); } else /* other channel medium types, see IPMI 1.5 Table 6-3 */ if (fdebug) printf("chan[%d] = %d\n",j,mtype); } if (i == 0) return(-2); /* no lan channels found */ if (fdebug) printf("lan_ch detected = %d\n",lan_ch); /* This will work if the BMC MAC is shared with the OS */ /* Otherwise, wait until we get the eth dev from the gateway below */ devnum = FindEthNum(bmcMacAddress); if ( fdebug ) printf("GetBmcEthDevice: channel %d, %s%d\n",lan_ch,ifpattn,devnum); return devnum; } /* file_grep/findmatch - No longer used here, see ievents.c */ /* * Get_Mac * This routine finds a MAC address from a given IP address. * Usually for the Alert destination. * It uses ARP cache to do this. */ #if defined(WIN32) int Get_Mac(uchar *ipadr,uchar *macadr, char *nodname) { DWORD dwRetVal; IPAddr DestIp = 0; IPAddr SrcIp = 0; /* default for src ip */ ULONG MacAddr[2]; /* for 6-byte hardware addresses */ ULONG PhysAddrLen = MAC_LEN; /* default to length of six bytes */ BYTE *bPhysAddr; if (!IpIsValid(ipadr)) { if (fdebug) printf("Get_Mac: invalid IP addr\n"); return 1; /*error*/ } memcpy(&DestIp, ipadr, 4); /* invoke system ARP query */ dwRetVal = SendARP(DestIp, SrcIp, MacAddr, &PhysAddrLen); if (dwRetVal == NO_ERROR) { /* no error - get the MAC */ bPhysAddr = (BYTE *) & MacAddr; if (PhysAddrLen) { memcpy(macadr, bPhysAddr, MAC_LEN); } else printf("Warning: SendArp completed successfully, but returned length=0\n"); } else if (dwRetVal == ERROR_GEN_FAILURE) { /* MAC not available in this network - get gateway MAC */ memcpy(macadr, rggwymac, MAC_LEN); } else { /* other errors */ printf("Error: SendArp failed with error: %d", dwRetVal); switch (dwRetVal) { case ERROR_INVALID_PARAMETER: printf(" (ERROR_INVALID_PARAMETER)\n"); break; case ERROR_INVALID_USER_BUFFER: printf(" (ERROR_INVALID_USER_BUFFER)\n"); break; case ERROR_BAD_NET_NAME: printf(" (ERROR_GEN_FAILURE)\n"); break; case ERROR_BUFFER_OVERFLOW: printf(" (ERROR_BUFFER_OVERFLOW)\n"); break; case ERROR_NOT_FOUND: printf(" (ERROR_NOT_FOUND)\n"); break; default: printf("\n"); break; } return 1; } return 0; } /* end Get_Mac() for WIN32*/ #elif defined(SOLARIS) int Get_Mac(uchar *ipadr,uchar *macadr, char *nodename) { FILE *fparp; char buff[1024]; /* char arpfile[] = "/proc/net/arp"; */ char alertfile[] = "/tmp/dest.arping"; char arping_cmd[128]; char *pb, *pm; int num, i; int foundit = 0; int ret = 0; if (IpIsValid(ipadr)) { /* if valid IP address */ sprintf(arping_cmd, "ping %d.%d.%d.%d >/dev/null; arp -a -n |grep %d.%d.%d.%d >%s\n", ipadr[0],ipadr[1],ipadr[2],ipadr[3], ipadr[0],ipadr[1],ipadr[2],ipadr[3], alertfile); } else if (nodename != NULL) { /*if valid nodename */ sprintf(arping_cmd, "ping %s >/dev/null; arp -a |grep %s >%s\n", nodename,nodename,alertfile); } else ret = -1; if (ret == 0) { /* if valid IP address */ /* make sure the destination is in the arp cache */ if (fdebug) printf("%s", arping_cmd); system(arping_cmd); fparp = fopen(alertfile,"r"); if (fparp == NULL) { fprintf(stdout,"Get_Mac: Cannot open %s, errno = %d\n", alertfile,get_errno()); ret = -1; } else { /* sample output: */ /* e1000g0 cooper9 255.255.255.255 o 00:07:e9:06:55:c8 */ while (fgets(buff, 1023, fparp)) { /* should only run through loop once */ num = strcspn(buff," \t"); /* skip 1st word ("e1000g0") */ i = strspn(&buff[num]," \t"); /* skip whitespace */ pb = &buff[num+i]; num = strcspn(pb," \t"); /* skip 2nd word (nodename/IP) */ i = strspn(&pb[num]," \t"); /* skip whitespace */ pb += (num+i); pm = &pb[25]; /* Now pb[25] has the MAC address */ { /*validate new address?*/ if (fdebug) printf("Get_Mac: mac=%s\n",pm); foundit = 1; if (!MacIsValid(macadr)) atomac(macadr,pm); break; } } /*end while*/ fclose(fparp); } /*end else file opened*/ } /*endif valid IP */ if (foundit == 0) { /* no errors, but no mac reply */ if (MacIsValid(rggwymac) && !MacIsValid(macadr)) /* this is useful if the ipadr is not in the local subnet */ memcpy(macadr,rggwymac,6); /* get to it from the default gateway */ } return(ret); } /*end Get_Mac for Solaris*/ #elif defined(BSD) int Get_Mac(uchar *ipadr,uchar *macadr, char *nodename) { FILE *fparp; char buff[1024]; /* char arpfile[] = "/proc/net/arp"; */ char alertfile[] = "/tmp/dest.arping"; char arping_cmd[128]; char *pb, *pm; int num, i, j; int foundit = 0; int ret = 0; if (IpIsValid(ipadr)) { /* if valid IP address */ sprintf(arping_cmd, "ping -c2 %d.%d.%d.%d >/dev/null; arp -a -n |grep %d.%d.%d.%d >%s\n", ipadr[0],ipadr[1],ipadr[2],ipadr[3], ipadr[0],ipadr[1],ipadr[2],ipadr[3], alertfile); } else if (nodename != NULL) { /*if valid nodename */ sprintf(arping_cmd, "ping -c2 %s >/dev/null; arp -a |grep %s >%s\n", nodename,nodename,alertfile); } else ret = -1; if (ret == 0) { /* if valid IP address */ /* make sure the destination is in the arp cache */ if (fdebug) printf("%s", arping_cmd); system(arping_cmd); fparp = fopen(alertfile,"r"); if (fparp == NULL) { fprintf(stdout,"Get_Mac: Cannot open %s, errno = %d\n", alertfile,get_errno()); ret = -1; } else { /* sample output of arp -a -n: */ /* ? (192.168.1.200) at 00:0e:0c:e5:df:65 on em0 [ethernet] */ /* sample output of arp -a: */ /* telcoserv (192.168.1.200) at 00:0e:0c:e5:df:65 on em0 [ethernet] */ while (fgets(buff, 1023, fparp)) { /* should only run through loop once */ pb = &buff[0]; for (j = 0; j < 3; j++) { /* skip 3 words */ num = strcspn(pb," \t"); /* skip jth word */ i = strspn(&pb[num]," \t"); /* skip whitespace */ pb += (num+i); } pm = &pb[0]; /* Now pb[0] has the MAC address */ { /* no need to validate new address*/ if (fdebug) printf("Get_Mac: mac=%s\n",pm); foundit = 1; if (!MacIsValid(macadr)) atomac(macadr,pm); break; } } /*end while*/ fclose(fparp); } /*end else file opened*/ } /*endif valid IP */ if (foundit == 0) { /* no errors, but no mac reply */ if (MacIsValid(rggwymac) && !MacIsValid(macadr)) /* this is useful if the ipadr is not in the local subnet */ memcpy(macadr,rggwymac,6); /* get to it from the default gateway */ } return(ret); } /*end Get_Mac for BSD */ #else int Get_Mac(uchar *ipadr,uchar *macadr, char *nodename) { /* Get_Mac for Linux */ FILE *fparp; char buff[1024]; /* char arpfile[] = "/proc/net/arp"; */ char alertfile[] = "/tmp/dest.arping"; char arping_cmd[128]; char *pb, *pm, *px; int num, i; int foundit = 0; int ret = 0; char *_ifname; if (strcmp(ifname,"gcm") == 0) _ifname = ifname0; /*see gcm_ch instead*/ else _ifname = ifname; /* Get a MAC address for a given IP address or nodename */ if (IpIsValid(ipadr)) { /* if valid IP address */ sprintf(arping_cmd, "arping -I %s -c 2 %d.%d.%d.%d |grep reply |tail -n1 >%s\n", _ifname,ipadr[0],ipadr[1],ipadr[2],ipadr[3],alertfile); } else if (nodename != NULL) { /*if valid nodename */ sprintf(arping_cmd, "arping -I %s -c 2 %s |grep reply |tail -n1 >%s\n", _ifname,nodename,alertfile); } else ret = -1; if (ret == 0) { /* if valid IP address */ /* make sure the destination is in the arp cache */ if (fdebug) printf("%s", arping_cmd); ret = system(arping_cmd); fparp = fopen(alertfile,"r"); if (fparp == NULL) { fprintf(stdout,"Get_Mac: Cannot open %s, errno = %d\n", alertfile,get_errno()); ret = -1; } else { ret = 0; while (fgets(buff, 1023, fparp)) { /* should only run through loop once */ num = strcspn(buff," \t"); /* skip 1st word ("Unicast") */ i = strspn(&buff[num]," \t"); pb = &buff[num+i]; if (strncmp(pb,"reply",5) == 0) { /* valid output */ /* Find the ip address */ pb += 6 + 5; /* skip "reply from " */ num = strcspn(pb," \t"); pb[num] = 0; if (fdebug) printf("Get_Mac: ip=%s\n",pb); /* IP address should already match input param */ if (!IpIsValid(ipadr)) /* had nodname only*/ atoip(ipadr,pb); /* fill in ipadr */ /* Now find the mac address */ pm = strchr(&pb[num+1],'['); if (pm == NULL) pm = &pb[num+2]; /* just in case */ pm++; px = strchr(pm,']'); if (px == NULL) px = pm + 17; /* just in case */ px[0] = 0; if (fdebug) printf("Get_Mac: mac=%s\n",pm); foundit = 1; if (!MacIsValid(macadr)) atomac(macadr,pm); break; } } /*end while*/ fclose(fparp); } /*end else file opened*/ } /*endif valid IP */ if (foundit == 0) { /* no errors, but no mac reply */ if (MacIsValid(rggwymac) && !MacIsValid(macadr)) /* this is useful if the ipadr is not in the local subnet */ memcpy(macadr,rggwymac,6); /* get to it from the default gateway */ } return(ret); } /* end Get_Mac() for Linux*/ #endif #ifdef WIN32 /* * Set subnet mask based on current IP address (Windows). */ int SetSubnetMask() { PMIB_IPADDRTABLE pIPAddrTable; unsigned int i; DWORD dwSize = 0, dwRetVal; LPVOID lpMsgBuf; pIPAddrTable = (MIB_IPADDRTABLE*) malloc( sizeof( MIB_IPADDRTABLE) ); if ( pIPAddrTable ) { // Make an initial call to GetIpAddrTable to get the // necessary size into the dwSize variable if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { free( pIPAddrTable ); pIPAddrTable = (MIB_IPADDRTABLE *) malloc ( dwSize ); } } else printf("Memory allocation failed.\n"); if ( pIPAddrTable ) { // Make a second call to GetIpAddrTable to get the // actual data we want if ( (dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 )) == NO_ERROR ) { for(i = 0; i < pIPAddrTable->dwNumEntries; ++i) { if(memcmp(&(pIPAddrTable->table[i].dwAddr), rgmyip, 4) == 0) { memcpy(rgsubnet, &(pIPAddrTable->table[i].dwMask), 4); free( pIPAddrTable ); return 1; } } } else { if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL )) { printf("\tError: %s", lpMsgBuf); } printf("Call to GetIpAddrTable failed.\n"); } } if ( pIPAddrTable ) free( pIPAddrTable ); return 0; } /* * Extract gateway address from routing table (Windows). */ int SetDefaultGateway() { PMIB_IPFORWARDTABLE pIpForwardTable; DWORD dwRetVal, dwSize; unsigned int nord_mask; unsigned int nord_ip; unsigned int nord_net; unsigned int i; nord_mask = *((unsigned int *)rgsubnet); nord_ip = *((unsigned int *)rgmyip); nord_net = nord_ip & nord_mask; pIpForwardTable = (MIB_IPFORWARDTABLE*) malloc(sizeof(MIB_IPFORWARDTABLE)); if (pIpForwardTable == NULL) { printf("Error allocating memory\n"); return 0; } dwSize = 0; if (GetIpForwardTable(pIpForwardTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { free(pIpForwardTable); pIpForwardTable = (MIB_IPFORWARDTABLE*) malloc(dwSize); if (pIpForwardTable == NULL) { printf("Error allocating memory\n"); return 0; } } /* * Note that the IPv4 addresses returned in * GetIpForwardTable entries are in network byte order */ if ((dwRetVal = GetIpForwardTable(pIpForwardTable, &dwSize, 0)) == NO_ERROR) { for (i = 0; i < (int) pIpForwardTable->dwNumEntries; i++) { unsigned int gwaddr = pIpForwardTable->table[i].dwForwardNextHop; if(nord_net == (gwaddr & nord_mask) && nord_ip != gwaddr) { /* searching for gateways from our network with different address than ours */ memcpy(rggwyip, &gwaddr, 4); return 0; } } free(pIpForwardTable); return 1; } else { printf("\tGetIpForwardTable failed.\n"); free(pIpForwardTable); return 0; } } /*endif WIN32*/ #endif /* * Get_IPMac_Addr * This routine finds the IP and MAC for the local interface, * the default gateway, and SNMP alert destination from the * BMC and OS information. * * Linux snmpd.conf locations (see ipmiutil.spec): * RedHat, MontaVista: /etc/snmp/snmpd.conf * SuSE SLES 8: /etc/ucdsnmpd.conf * SuSE SLES 9: /etc/snmpd.conf */ #ifdef WIN32 int Get_IPMac_Addr() { /*for Windows*/ char ipstr[] = "IP Address"; char macstr[] = "Physical Address"; char gwystr[] = "Default Gateway"; char substr[] = "Subnet Mask"; int found = 0; char fgetmac; if (IpIsValid(rgmyip)) { /* user-specified ip, get mac */ if (fdebug) printf("User IP was specified\n"); if (!MacIsValid(rgmymac)) { /* no user-specified MAC, get it from IP */ if (fdebug) printf("No user MAC specified\n"); if(!GetLocalMACByIP()) { /* couldn't get MAC from IP, get old one */ if (fdebug) printf("No MAC from IP, use old\n"); if(IpIsValid(bmcmyip) && MacIsValid(bmcmymac)) { printf("Using current BMC MAC %02x:%02x:%02x:%02x:%02x:%02x\n", bmcmymac[0], bmcmymac[1], bmcmymac[2], bmcmymac[3], bmcmymac[4], bmcmymac[5]); memcpy(rgmymac,bmcmymac,MAC_LEN); } else { printf("Failed to obtain valid MAC\n"); } } else { printf("Using adapter MAC %02x:%02x:%02x:%02x:%02x:%02x\n", rgmymac[0], rgmymac[1], rgmymac[2], rgmymac[3], rgmymac[4], rgmymac[5]); } } else { /* user MAC available */ printf("Using user MAC %02x:%02x:%02x:%02x:%02x:%02x\n", rgmymac[0], rgmymac[1], rgmymac[2], rgmymac[3], rgmymac[4], rgmymac[5]); } } else { /* no user-specified IP */ if (fdebug) printf("No user IP specified\n"); if (!MacIsValid(rgmymac)) { /* no user-specified MAC, get it from interface */ if(!GetLocalDataByIface()) { /* use existing MAC an IP */ printf("Using current BMC IP %d.%d.%d.%d\n", bmcmyip[0], bmcmyip[1], bmcmyip[2], bmcmyip[3]); memcpy(rgmyip,bmcmyip,4); printf("Using current BMC MAC %02x:%02x:%02x:%02x:%02x:%02x\n", bmcmymac[0], bmcmymac[1], bmcmymac[2], bmcmymac[3], bmcmymac[4], bmcmymac[5]); memcpy(rgmymac,bmcmymac,MAC_LEN); } } else { /* user-specified MAC */ if(!GetLocalIPByMAC(rgmymac)) { /* use existing MAC and IP */ printf("Using current BMC IP %d.%d.%d.%d\n", bmcmyip[0], bmcmyip[1], bmcmyip[2], bmcmyip[3]); memcpy(rgmyip,bmcmyip,4); printf("Using current BMC MAC %02x:%02x:%02x:%02x:%02x:%02x\n", bmcmymac[0], bmcmymac[1], bmcmymac[2], bmcmymac[3], bmcmymac[4], bmcmymac[5]); memcpy(rgmymac,bmcmymac,MAC_LEN); } } } if (rghostname[0] == 0) { /*hostname not specified*/ if (!fipmilan) gethostname(rghostname,sizeof(rghostname)); } if (fdebug) /* show the local OS eth if and MAC */ printf("OS %s IP=%d.%d.%d.%d %s MAC=%02x:%02x:%02x:%02x:%02x:%02x used for arp\n", ifname, osmyip[0],osmyip[1],osmyip[2],osmyip[3], rghostname, osmymac[0], osmymac[1], osmymac[2], osmymac[3], osmymac[4], osmymac[5]); if(!SubnetIsValid(rgsubnet)) { SetSubnetMask(); } if (!IpIsValid(rggwyip)) { /* if gwy ip not user-specified */ SetDefaultGateway(); } if (lan_ch == gcm_ch) { if (SubnetIsSame(rgmyip,rggwyip,rgsubnet)) fgetmac = 1; else fgetmac = 0; } else fgetmac = 1; if (fgetmac) { if (IpIsValid(rggwyip) && !MacIsValid(rggwymac)) /*gwy mac not specified*/ Get_Mac(rggwyip,rggwymac,NULL); if (IpIsValid(rggwy2ip) && !MacIsValid(rggwy2mac)) /*gwy2 mac not valid*/ Get_Mac(rggwy2ip,rggwy2mac,NULL); } return(0); } /* end Get_IPMac_Addr for Windows */ #elif defined(HPUX) int Get_IPMac_Addr() { /*for HP-UX*/ return(-1); } #else int Get_IPMac_Addr() { /*for Linux*/ #if defined(SOLARIS) char rtfile[] = "/tmp/route"; char snmpfile[] = "/etc/snmp/conf/snmpd.conf"; #elif defined(BSD) char rtfile[] = "/tmp/route"; char snmpfile[] = "/etc/snmpd.config"; #else char rtfile[] = "/proc/net/route"; char snmpfile[] = "/etc/snmp/snmpd.conf"; #endif // char alertfile[] = "/tmp/alert.arping"; // FILE *fparp; FILE *fprt; int fd = -1; int skfd; uchar *pc; int rc = 0; int i,j; uchar bnetadr[4]; uchar bgateadr[4]; char gate_addr[128]; char iface[16]; char defcommunity[19] = "public"; char buff[1024]; char alertname[60]; int num, nmatch; struct ifreq ifr; char *_ifname; char fgetmac; /* Get the IP address and associated MAC address specified. */ /* Local for ethN; Default Gateway; Alert Destination */ /* Get the default gateway IP */ #if defined(SOLARIS) || defined(BSD) char rtcmd[80]; sprintf(rtcmd,"netstat -r -n |grep default |awk '{ print $2 }' >%s",rtfile); system(rtcmd); /* use rtfile output from netstat -r, see also /etc/defaultroute */ fprt = fopen(rtfile,"r"); if (fprt == NULL) { fprintf(stdout,"netstat: Cannot open %s, errno = %d\n",rtfile,get_errno()); } else { while (fgets(buff, 1023, fprt)) { if ((buff[0] > '0') && (buff[0] <= '9')) { /*valid*/ atoip(bgateadr,buff); if (fdebug) printf("default gateway: %s, %d.%d.%d.%d %s\n",buff, bgateadr[0], bgateadr[1], bgateadr[2], bgateadr[3],ifname); if (!IpIsValid(rggwyip)) /* if not user-specified */ memcpy(rggwyip,bgateadr,4); break; } } fclose(fprt); } /*end-else good open */ #else /* cat /proc/net/route and save Gwy if Dest == 0 and Gateway != 0 */ fprt = fopen(rtfile,"r"); if (fprt == NULL) { fprintf(stdout,"route: Cannot open %s, errno = %d\n",rtfile,get_errno()); } else { char rtfmt[] = "%16s %128s %128s %X %d %d %d %128s %d %d %d\n"; int iflags, refcnt, use, metric, mss, window, irtt; char mask_addr[128], net_addr[128]; uint *pnet; uint *pgate; pnet = (uint *)&bnetadr[0]; pgate = (uint *)&bgateadr[0]; while (fgets(buff, 1023, fprt)) { num = sscanf(buff, rtfmt, iface, net_addr, gate_addr, &iflags, &refcnt, &use, &metric, mask_addr, &mss, &window, &irtt); if (num < 10 || !(iflags & RTF_UP)) continue; j = 6; for (i = 0; i < 4; i ++) { bnetadr[i] = htoi(&net_addr[j]); bgateadr[i] = htoi(&gate_addr[j]); j -= 2; } if ((*pnet == 0) && (*pgate != 0)) { /* found default gateway */ if (fdebug) printf("default gateway: %s, %d.%d.%d.%d %s\n",gate_addr, bgateadr[0], bgateadr[1], bgateadr[2], bgateadr[3],iface); if (!IpIsValid(rggwyip)) /* if not user-specified */ memcpy(rggwyip,bgateadr,4); _ifname = iface; /*use this iface for gwy mac */ if (!fsetifn) strncpy(ifname,iface,16); break; } } /*end while*/ fclose(fprt); } /*end-else good open */ #endif /* Create a channel to the NET kernel. */ if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); return(-3); } /* Find a valid local BMC MAC Address */ if (lan_ch == gcm_ch) { /* GCM has its own unique mac address */ if (!MacIsValid(rgmymac)) { if (MacIsValid(bmcmymac)) { memcpy(rgmymac,bmcmymac,MAC_LEN); /*use existing*/ } else { /*error*/ printf("invalid MAC address for gcm\n"); } } /*else use rgmymac if specified*/ _ifname = iface; /*use the iface from gwy (e.g. eth0) */ fsharedMAC = 0; /*gcm has separate NIC, separate MAC*/ // fd = -1; fd = skfd; // get_socket_for_af(AF_INET) below; } else { /*else not gcm*/ if (!fsetifn && !fethfound) { /*do not have ifname yet*/ i = FindEthNum(bmcmymac); if (i >= 0) sprintf(ifname,"%s%d",ifpattn,i); } ifr.ifr_addr.sa_family = AF_INET; if (fdebug) printf("getipmac: ifname=%s\n",ifname); _ifname = ifname; strcpy(ifr.ifr_name, _ifname); #ifdef SIOCGIFHWADDR /* Get the local if HWADDR (MAC Address) from OS */ if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) { if (fdebug) printf("ioctl(SIOCGIFHWADDR,%s) error, errno = %d\n",_ifname,get_errno()); } else memcpy(osmymac,get_ifreq_mac(&ifr),MAC_LEN); /*OS mac*/ #endif if (memcmp(bmcmymac,osmymac,MAC_LEN) == 0) { /* osmymac and ifname were set above by FindEthNum */ printf("\tBMC shares IP/MAC with OS NIC %s\n",_ifname); fsharedMAC = 1; } /* else fsharedMAC = 0; */ if (fsharedMAC == 0) { /* then BMC has separate MAC */ if (!MacIsValid(rgmymac) && MacIsValid(bmcmymac)) memcpy(rgmymac,bmcmymac,MAC_LEN); /*use existing*/ } else { /* else OS & BMC share a MAC */ /* Use the local if HWADDR (MAC Address) from OS */ if (!MacIsValid(rgmymac)) { /* if not user-specified */ if (MacIsValid(bmcmymac)) memcpy(rgmymac,bmcmymac,MAC_LEN); /*use existing*/ else memcpy(rgmymac,osmymac,MAC_LEN); /*use OS mac*/ } } fd = skfd; // get_socket_for_af(AF_INET) below; } if (fd >= 0) { /* if valid fd, find OS IP */ strcpy(ifr.ifr_name, _ifname); ifr.ifr_addr.sa_family = AF_INET; /* Get the IFADDR (IP Address) from OS */ if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) { int err; err = get_errno(); /* errno 99 here means that eth0 is not enabled/up/defined. */ if (err == 99) printf("ioctl(SIOCGIFADDR) error, %s not enabled\n",_ifname); else if (fdebug) printf("ioctl(SIOCGIFADDR,%s) error, errno=%d\n",_ifname,err); } else { /* got the local OS IP successfully */ pc = &ifr.ifr_addr.sa_data[2]; if (fdebug) printf("%s addr = %d.%d.%d.%d\n",_ifname,pc[0],pc[1],pc[2],pc[3]); memcpy(osmyip, pc, 4); if (!IpIsValid(rgmyip) && (fsharedMAC==1)) /*not specified, shared*/ memcpy(rgmyip, osmyip, 4); /* get the local OS netmask */ strcpy(ifr.ifr_name, _ifname); if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0) { if (fdebug) printf("ioctl(SIOCGIFNETMASK) error, errno=%d\n",get_errno()); /* if leave invalid, will use default rgsubnet */ } else { // sizeof(struct sockaddr) pc = &ifr.ifr_netmask.sa_data[2]; if (fdebug) printf("subnet = %d.%d.%d.%d \n", pc[0],pc[1],pc[2],pc[3]); memcpy(ossubnet, pc, 4); if (!SubnetIsValid(rgsubnet) && fsharedMAC) /*not specified*/ memcpy(rgsubnet, pc, 4); } #ifdef SIOCGIFHWADDR /* Get the localhost OS HWADDR (MAC Address) */ if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { if (fdebug) printf("ioctl(SIOCGIFHWADDR,%s) error, errno = %d\n", _ifname,get_errno()); } else memcpy(osmymac,get_ifreq_mac(&ifr),MAC_LEN); /*OS mac*/ #endif } } close(skfd); /* done, close the socket */ if (rghostname[0] == 0) { /*hostname not specified*/ if (!fipmilan) gethostname(rghostname,sizeof(rghostname)); } if (fdebug) /* show the local OS eth if and MAC */ printf("OS %s IP=%d.%d.%d.%d %s MAC=%02x:%02x:%02x:%02x:%02x:%02x used for arp\n", _ifname, osmyip[0],osmyip[1],osmyip[2],osmyip[3], rghostname, osmymac[0], osmymac[1], osmymac[2], osmymac[3], osmymac[4], osmymac[5]); if (!IpIsValid(rgmyip) && IpIsValid(bmcmyip)) { /* If no user-specified IP and there is a valid IP already in the * BMC LAN configuration, use the existing BMC LAN IP. */ memcpy(rgmyip,bmcmyip,4); if (fdebug) printf("Using current IP %d.%d.%d.%d\n", bmcmyip[0], bmcmyip[1], bmcmyip[2], bmcmyip[3]); } /* Get the default gateway MAC */ if (lan_ch == gcm_ch) { if (SubnetIsSame(osmyip,rggwyip,ossubnet)) fgetmac = 1; else { /* gateway is not on the same subnet as RMM/GCM */ fgetmac = 0; /*don't try to get mac if not the same subnet*/ if ((fset_ip & GWYIP) == 0) memset(rggwyip,0,4); } } else fgetmac = 1; if (fgetmac && IpIsValid(rggwyip) && !MacIsValid(rggwymac)) Get_Mac(rggwyip,rggwymac,NULL); /*gwy mac not specified, so get mac*/ /* Get the Alert Destination IP */ /* By default, attempt to obtain this from /etc/snmp/snmpd.conf. */ /* cat /etc/snmp/snmpd.conf | grep trapsink |tail -n1 | cut -f2 -d' ' */ alertname[0] = 0; /* default to null string */ fprt = fopen(snmpfile,"r"); if (fprt == NULL) { printf("snmp: Cannot open %s, errno = %d\n",snmpfile,get_errno()); } else { // char snmpfmt[] = "%20s %60s\n"; // char *keywd, *value; while (fgets(buff, 1023, fprt)) { /* parse each line */ if (buff[0] == '#') continue; /*skip comment lines*/ /* skip leading whitespace here */ j = strspn(&buff[0]," \t"); if (strncmp(&buff[j],"com2sec",7) == 0) { /* found community line */ /* usu like this: "com2sec demouser default public" */ i = j + 7; for (j = 0; j < 3; j++) { num = strspn(&buff[i]," \t"); i += num; num = strcspn(&buff[i]," \t\r\n"); if (j < 2) i += num; } buff[i+num] = 0; if (fsetcommunity == 0) { /* if not user-specified */ strcpy(rgcommunity,&buff[i]); strcpy(defcommunity,&buff[i]); } } #ifdef BSD if (strncmp(&buff[j],"traphost :=",11) == 0) nmatch = 11; else nmatch = 0; #else if (strncmp(&buff[j],"trapsink",8) == 0) nmatch = 8; else if (strncmp(&buff[j],"trap2sink",9) == 0) nmatch = 9; else nmatch = 0; #endif if (nmatch > 0) { /* found trapsink line match */ if (fdebug) printf("%s: %s",snmpfile,&buff[j]); num = strspn(&buff[j+nmatch]," \t"); i = j + nmatch + num; if (buff[i] == '`') continue; num = strcspn(&buff[i]," \t\r\n"); strncpy(alertname,&buff[i],num); /* save alert destination */ alertname[num] = 0; i += num; num = strspn(&buff[i]," \t"); /*skip whitespace*/ i += num; num = strcspn(&buff[i]," \t\r\n"); /*span next word*/ if (num != 0) { /* there is another word, that is community */ if (fsetcommunity == 0) { /* if not user-specified */ strncpy(rgcommunity,&buff[i],num); /* save community */ rgcommunity[num] = 0; } } else { /*have trapsink node with no community*/ /* use previously discovered default community from above */ strcpy(rgcommunity,defcommunity); } /* dont break, keep looking, use the last one */ } } /*end while*/ fclose(fprt); if (fdebug) printf("snmp alertname=%s community=%s\n",alertname,rgcommunity); } /*end else snmpfile*/ /* Get the Alert Destination MAC from the alertname. */ if (alertname[0] != 0) { #ifdef TEST char arping_cmd[128]; char *pb, *pm, *px; int num, i; if (fdebug) printf("alert %s ip=%d.%d.%d.%d osip=%d.%d.%d.%d " "mac=%02x:%02x:%02x:%02x:%02x:%02x " "osmac=%02x:%02x:%02x:%02x:%02x:%02x\n", alertname, rgdestip[0], rgdestip[1], rgdestip[2], rgdestip[3], osmyip[0], osmyip[1], osmyip[2], osmyip[3], rgdestmac[0], rgdestmac[1], rgdestmac[2], rgdestmac[3], rgdestmac[4], rgdestmac[5], osmymac[0], osmymac[1], osmymac[2], osmymac[3], osmymac[4], osmymac[5]); #endif if (!IpIsValid(rgdestip)) { /* if not user-specified with -A */ if (IpIsValid(bmcdestip)) { /* use existing if valid */ memcpy(rgdestip,bmcdestip,4); if (MacIsValid(bmcdestmac)) memcpy(rgdestmac,bmcdestmac,MAC_LEN); } else if ((strncmp(alertname,"localhost",9) == 0) ) { /* snmpd.conf = localhost (self) is the SNMP alert destination */ if (IpIsValid(osmyip)) memcpy(rgdestip,osmyip,4); if (!MacIsValid(rgdestmac)) { /* if not user-specified */ // Get_Mac(rgdestip,rgdestmac,alertname); (wont work for local) memcpy(rgdestmac,osmymac,MAC_LEN); } } /*endif local */ } if (!MacIsValid(rgdestmac)) /* if MAC not vaild or user-specified */ { /* Use arping to get MAC from alertname or IP */ Get_Mac(rgdestip,rgdestmac,alertname); } } /*endif have alertname*/ return(rc); } /* end Get_IPMac_Addr */ #endif int ShowChanAcc(uchar bchan) { LAN_RECORD LanRecord; int ret = 0; uchar access; char *pstr; uchar pb0, pb1; if (bchan == lan_ch) pstr = "lan"; else if (bchan == ser_ch) pstr = "ser"; else pstr = "?"; ret = GetChanAcc(bchan, 0x40, &LanRecord); if (fdebug) printf(" GetChanAcc(%d), ret = %d, data = %02x %02x\n", bchan,ret, LanRecord.data[0], LanRecord.data[1]); pb0 = LanRecord.data[0]; pb1 = LanRecord.data[1]; if (fcanonical) printf("Channel %d Access Mode %s%c ",bchan,pspace3,bdelim); else printf("Channel(%d=%s) Access Mode: %02x %02x : ",bchan,pstr,pb0,pb1); access = pb0; switch (access & 0x03) { case 0: printf("Disabled, "); break; case 1: printf("Pre-Boot, "); break; case 2: printf("Always Avail, "); break; case 3: printf("Shared, "); break; } if (access & 0x20) printf("PEF Alerts Disabled\n"); /*0*/ else printf("PEF Alerts Enabled\n"); /*1*/ return(ret); } static int GetSessionInfo(uchar *rData, int sz) { int rv, rlen; uchar ccode; uchar iData[5]; iData[0] = 0x00; /*get data for this session*/ rlen = sz; rv = ipmi_cmdraw(CMD_GET_SESSION_INFO,NETFN_APP, BMC_SA,PUBLIC_BUS,BMC_LUN, iData,1,rData, &rlen, &ccode, fdebug); if ((rv == 0) && (ccode != 0)) rv = ccode; return(rv); } static int GetPefCapabilities(uchar *bmax) { int rv, rlen; uchar ccode; uchar rData[MAX_BUFFER_SIZE]; rlen = sizeof(rData); rv = ipmi_cmdraw(0x10, NETFN_SEVT, BMC_SA,PUBLIC_BUS,BMC_LUN, NULL,0,rData, &rlen, &ccode, fdebug); if ((rv == 0) && (ccode != 0)) rv = ccode; if ((rv == 0) && (bmax != NULL)) *bmax = rData[2]; /*max num PEF table entries*/ return(rv); } int GetSerialOverLan( uchar chan, uchar bset, uchar block ) { uchar requestData[24]; uchar rData[MAX_BUFFER_SIZE]; int rlen; int status, i; uchar ccode; uchar enable_parm, auth_parm, baud_parm; ushort getsolcmd; uchar user; if (fIPMI20 && fSOL20) { getsolcmd = GET_SOL_CONFIG2; enable_parm = SOL_ENABLE_PARAM; auth_parm = SOL_AUTHENTICATION_PARAM; baud_parm = SOL_BAUD_RATE_PARAM; } else { getsolcmd = GET_SOL_CONFIG; enable_parm = SOL_ENABLE_PARAM; auth_parm = SOL_AUTHENTICATION_PARAM; baud_parm = SOL_BAUD_RATE_PARAM; chan = 0; /*override chan for IPMI 1.5*/ } if (!fcanonical) printf("%s, GetSOL for channel %d ...\n",progname,chan); requestData[0] = chan; /*channel*/ requestData[1] = enable_parm; requestData[2] = bset; /*set*/ requestData[3] = block; /*block*/ rlen = sizeof(rData); status = ipmi_cmd(getsolcmd, requestData,4, rData, &rlen,&ccode,fdebug); if (status != 0) return(status); if (ccode) { if (ccode == 0xC1) { /* unsupported command */ printf("Serial-Over-Lan not available on this platform\n"); return(status); } else { printf("SOL Enable ccode = %x\n",ccode); status = ccode; } } else { /*success*/ if (fcanonical) { printf("Channel %d SOL Enable %s",chan,pspace3); } else { printf("SOL Enable: "); for (i = 1; i < rlen; i++) printf("%02x ",rData[i]); } if (rData[1] == 0x01) printf("%c enabled\n",bdelim); else printf("%c disabled\n",bdelim); } if (!fcanonical) { requestData[0] = chan; requestData[1] = auth_parm; requestData[2] = bset; // selector requestData[3] = block; // block rlen = sizeof(rData); status = ipmi_cmd(getsolcmd,requestData,4,rData,&rlen,&ccode,fdebug); if (status != 0) return(status); if (ccode) { printf("SOL Auth ccode = %x\n",ccode); status = ccode; } else { /*success*/ printf("SOL Auth: "); for (i = 1; i < rlen; i++) printf("%02x ",rData[i]); printf(": "); show_priv(rData[1]); /* priv level = User,Admin,... */ printf("\n"); } requestData[0] = chan; requestData[1] = SOL_ACC_INTERVAL_PARAM; requestData[2] = bset; requestData[3] = block; rlen = sizeof(rData); status = ipmi_cmd(getsolcmd,requestData,4,rData,&rlen,&ccode,fdebug); if (status != 0) return(status); if (ccode) { printf("SOL Accum Interval ccode = %x\n",ccode); status = ccode; } else { /*success*/ printf("SOL Accum Interval: "); for (i = 1; i < rlen; i++) printf("%02x ",rData[i]); printf(": %d msec\n",(rData[1] * 5)); } requestData[0] = chan; requestData[1] = SOL_RETRY_PARAM; requestData[2] = bset; requestData[3] = block; rlen = sizeof(rData); status = ipmi_cmd(getsolcmd,requestData,4,rData,&rlen,&ccode,fdebug); if (status != 0) return(status); if (ccode) { printf("SOL Retry ccode = %x\n",ccode); status = ccode; } else { /*success*/ printf("SOL Retry Interval: "); for (i = 1; i < rlen; i++) printf("%02x ",rData[i]); printf(": %d msec\n",(rData[2] * 10)); } } if (!fRomley) { requestData[0] = chan; requestData[1] = baud_parm; requestData[2] = bset; requestData[3] = block; rlen = sizeof(rData); status = ipmi_cmd(getsolcmd,requestData,4,rData, &rlen,&ccode,fdebug); if (status != 0) return(status); if (ccode) { printf("SOL nvol Baud ccode = %x\n",ccode); status = ccode; } else { /*success*/ uchar b; if (fcanonical) { printf("Channel %d SOL Baud Rate%s",chan,pspace3); } else { printf("SOL nvol Baud Rate: "); for (i = 1; i < rlen; i++) printf("%02x ",rData[i]); } /* if not user-specified and previously enabled, use existing */ b = (rData[1] & 0x0f); if ((fnewbaud == 0) && BaudValid(b)) { sol_baud = b; sol_bvalid = 1; } printf("%c %s\n",bdelim,Baud2Str(b)); } if (!fcanonical) { requestData[0] = chan; requestData[1] = SOL_VOL_BAUD_RATE_PARAM; /*0x06*/ requestData[2] = bset; requestData[3] = block; rlen = sizeof(rData); status = ipmi_cmd(getsolcmd,requestData,4,rData,&rlen,&ccode,fdebug); if (status != 0) return(status); if (ccode) { printf("SOL vol Baud ccode = %x\n",ccode); status = ccode; } else { /*success*/ printf("SOL vol Baud Rate: "); for (i = 1; i < rlen; i++) printf("%02x ",rData[i]); printf("%c %s\n",bdelim,Baud2Str(rData[1])); } } } if (fIPMI20) { if (vend_id != VENDOR_IBM) { /* IBM 0x00DC returns invalid cmd for SOL Payload commands. */ if (!fcanonical) { requestData[0] = chan; rlen = sizeof(rData); status = ipmi_cmdraw(GET_PAYLOAD_SUPPORT, NETFN_APP, BMC_SA,PUBLIC_BUS,BMC_LUN, requestData,1,rData, &rlen, &ccode, fdebug); if ((status != 0) || (ccode != 0)) { printf("SOL Payload Support error %d, ccode = %x\n",status,ccode); if (status == 0) status = ccode; } else { /*success*/ printf("SOL Payload Support(%d): ",chan); for (i = 0; i < rlen; i++) printf("%02x ",rData[i]); printf("\n"); } } /*endif not canonical*/ /* get Payload Access for 4 users, not just lan_user */ for (user = 1; user <= show_users; user++) { /* mBMC doesn't support more than 1 user */ if (fmBMC && (user > 1)) break; /* IPMI 2.0 has >= 4 users */ requestData[0] = chan; requestData[1] = user; rlen = sizeof(rData); status = ipmi_cmdraw(GET_PAYLOAD_ACCESS, NETFN_APP, BMC_SA,PUBLIC_BUS,BMC_LUN, requestData,2,rData, &rlen, &ccode, fdebug); if ((status != 0) || (ccode != 0)) { printf("SOL Payload Access(%d,%d) error %d, ccode = %x\n", chan,user,status,ccode); if (status == 0) status = ccode; } else { /*success*/ if (fcanonical) { printf("Channel %d SOL Payload Access(user%d)%s",chan,user, pspace1); } else { printf("SOL Payload Access(%d,%d): ",chan,user); for (i = 0; i < rlen; i++) printf("%02x ",rData[i]); } if ((rData[0] & 0x02) != 0) printf("%c enabled\n",bdelim); else printf("%c disabled\n",bdelim); } } /*end user loop*/ } /*endif not IBM*/ } return(status); } /*end GetSerialOverLan */ /* ECHO SOL Config Enable CMDTOOL 20 30 21 %1 01 01 ECHO SOL Authentication (Administrator) CMDTOOL 20 30 21 %1 02 04 ECHO SOL Accumlate Interval and threshold CMDTOOL 20 30 21 %1 03 06 14 ECHO SOL Retry Interval and threshold CMDTOOL 20 30 21 %1 04 06 14 ECHO SOL non-volatile baud rate CMDTOOL 20 30 21 %1 05 07 ECHO SOL volatile baud rate CMDTOOL 20 30 21 %1 06 07 ECHO Set user Payload Access for user 1 CMDTOOL 20 18 4c %1 01 02 00 00 00 */ int SetupSerialOverLan( int benable ) { uchar requestData[24]; uchar responseData[MAX_BUFFER_SIZE]; int responseLength = MAX_BUFFER_SIZE; int status; uchar completionCode; uchar enable_parm, auth_parm, baud_parm; ushort setsolcmd; ushort getsolcmd; uchar bchan, b; if (fIPMI20 && fSOL20) { setsolcmd = SET_SOL_CONFIG2; getsolcmd = GET_SOL_CONFIG2; enable_parm = SOL_ENABLE_PARAM; auth_parm = SOL_AUTHENTICATION_PARAM; baud_parm = SOL_BAUD_RATE_PARAM; bchan = lan_ch; } else { setsolcmd = SET_SOL_CONFIG; getsolcmd = GET_SOL_CONFIG; enable_parm = SOL_ENABLE_PARAM; auth_parm = SOL_AUTHENTICATION_PARAM; baud_parm = SOL_BAUD_RATE_PARAM; bchan = 0x00; /*override chan for IPMI 1.5*/ } memset(requestData, 0, sizeof(requestData)); /* zero-fill */ requestData[0] = bchan; requestData[1] = enable_parm; if (benable == 0) requestData[2] = SOL_DISABLE_FLAG; else requestData[2] = SOL_ENABLE_FLAG; responseLength = MAX_BUFFER_SIZE; status = ipmi_cmd(setsolcmd, requestData,3,responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { switch( completionCode ) { case 0x00: /* success */ break; case 0xC1: /* unsupported command */ SELprintf("SetupSerialOverLan: SOL not available on this platform\n"); return 0; default: /* other error */ SELprintf("SetupSerialOverLan: SOL_ENABLE_PARAM ccode=%x\n", completionCode); return -1; break; } } else { SELprintf( "SET_SOL_CONFIG, enable SOL failed\n" ); return -1; } if (benable == 0) return 0; requestData[0] = bchan; /* channel */ requestData[1] = auth_parm; requestData[2] = 0x00; /* set selector */ requestData[3] = 0x00; /* block selector */ responseLength = MAX_BUFFER_SIZE; status = ipmi_cmd(getsolcmd, requestData,4,responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { if( completionCode ) { SELprintf("SetupSerialOverLan: GET_SOL_AUTHENTICATION_PARAM code=%x\n", completionCode); return -1; } } else { SELprintf( "SOL_CONFIG, get SOL authentication failed\n" ); return -1; } if ((vend_id == VENDOR_SUPERMICROX) || (vend_id == VENDOR_SUPERMICRO)) b = SOL_PRIVILEGE_LEVEL_OPERATOR; else b = SOL_PRIVILEGE_LEVEL_USER; requestData[0] = bchan; requestData[1] = auth_parm; requestData[2] = b | ( responseData[1] & 0x80 ); /* priv | enable */ responseLength = MAX_BUFFER_SIZE; status = ipmi_cmd(setsolcmd, requestData,3,responseData, &responseLength, &completionCode, fdebug); if (status == ACCESS_OK) { if( completionCode ) { SELprintf("SET_SOL_AUTHENTICATION_PARAM code=%x\n", completionCode); return -1; } } else { SELprintf( "SET_SOL_CONFIG, set SOL authentication failed\n" ); return -1; } requestData[0] = bchan; requestData[1] = SOL_ACC_INTERVAL_PARAM; requestData[2] = sol_accum[0]; //0x04; requestData[3] = sol_accum[1]; //0x32; responseLength = MAX_BUFFER_SIZE; if (fdebug) SELprintf("Setting SOL AccumInterval\n"); status = ipmi_cmd(setsolcmd, requestData,4,responseData, &responseLength, &completionCode, fdebug); if (status != ACCESS_OK || completionCode) { SELprintf("SET SOL AccumInterval ret=%d ccode=%x\n", status,completionCode); return -1; } /* Some BMCs return sporadic errors for SOL params (e.g. Kontron)*/ // if (vend_id == VENDOR_KONTRON) ; // else { requestData[0] = bchan; requestData[1] = SOL_RETRY_PARAM; requestData[2] = sol_retry[0]; //0x06; requestData[3] = sol_retry[1]; //0x14; responseLength = MAX_BUFFER_SIZE; if (fdebug) SELprintf("Setting SOL RetryInterval\n"); status = ipmi_cmd(setsolcmd, requestData,4,responseData, &responseLength, &completionCode, fdebug); if (status != ACCESS_OK || completionCode) { SELprintf("SET SOL RetryInterval ret=%d ccode=%x\n", status,completionCode); return -1; } } if (fRomley) ; /* skip SOL BAUD */ else { /* else SOL BAUD is used, so set it. */ if (fnewbaud == 0) { /* no user-specified SOL baud */ /* if sol_bvalid, sol_baud was set to existing value above */ if (!sol_bvalid) { status = GetSerEntry(7, (LAN_RECORD *)&responseData); if (status == 0) { /* use Serial baud for SOL */ sol_baud = responseData[1]; if (fdebug) SELprintf("Serial Baud is %s\n",Baud2Str(sol_baud)); } } } requestData[0] = bchan; requestData[1] = baud_parm; requestData[2] = sol_baud; responseLength = MAX_BUFFER_SIZE; if (fdebug) SELprintf("Setting SOL BAUD to %s\n",Baud2Str(sol_baud)); status = ipmi_cmd(setsolcmd, requestData,3,responseData, &responseLength, &completionCode, fdebug); if (status != ACCESS_OK || completionCode) { SELprintf("SET SOL BAUD ret=%d ccode=%x\n", status,completionCode); return -1; } requestData[0] = bchan; requestData[1] = SOL_VOL_BAUD_RATE_PARAM; requestData[2] = sol_baud; responseLength = MAX_BUFFER_SIZE; if (fdebug) printf("Setting SOL vol BAUD to %s\n",Baud2Str(sol_baud)); status = ipmi_cmd(setsolcmd, requestData,3,responseData, &responseLength, &completionCode, fdebug); if (status != ACCESS_OK || completionCode) { printf("SET SOL vol BAUD ret=%d ccode=%x\n",status,completionCode); return -1; } } if (fIPMI20 && fSOL20) { if (vend_id == VENDOR_KONTRON && lan_user == 1) { if (fdebug) SELprintf("Skipping SOL Payload Access for user %d\n", lan_user); } else if (vend_id == VENDOR_IBM) { /*non-conformance*/ if (fdebug) SELprintf("Skipping SOL Payload Access for user %d\n", lan_user); } else { if (fdebug) SELprintf("Setting SOL Payload Access for user %d\n", lan_user); requestData[0] = bchan; requestData[1] = lan_user; /*enable this user*/ requestData[2] = 0x02; /*enable std 2.0 SOL*/ requestData[3] = 0; requestData[4] = 0; requestData[5] = 0; responseLength = MAX_BUFFER_SIZE; status = ipmi_cmdraw(SET_PAYLOAD_ACCESS, NETFN_APP, BMC_SA,PUBLIC_BUS,BMC_LUN, requestData,6,responseData, &responseLength, &completionCode, fdebug); if (status != ACCESS_OK || completionCode) { SELprintf("SET SOL Payload Access ret=%d ccode=%x\n", status,completionCode); return -1; } } } return 0; } /*end SetupSerialOverLan */ static char *PefDesc(int idx, uchar stype) { char *pdesc, *p; static char mystr[60]; int mylen = sizeof(mystr); pdesc = &mystr[0]; if (pefdesc != NULL) strcpy(pdesc,pefdesc[idx]); /* if Intel, pre-defined */ else strcpy(pdesc,"reserved"); /* else set default to detect */ if ((stype != 0) && (strcmp(pdesc,"reserved") == 0)) { /* Dynamically set the pef desc string from the sensor type */ switch(stype) { case 0x01: strcpy(pdesc,"Temperature"); break; case 0x02: strcpy(pdesc,"Voltage"); break; case 0x04: strcpy(pdesc,"Fan"); break; case 0x05: strcpy(pdesc,"Chassis"); break; case 0x07: strcpy(pdesc,"BIOS"); break; case 0x08: strcpy(pdesc,"Power Supply"); break; case 0x09: strcpy(pdesc,"Power Unit"); break; case 0x0c: strcpy(pdesc,"Memory"); break; case 0x0f: strcpy(pdesc,"Boot"); break; case 0x12: strcpy(pdesc,"System Restart"); break; case 0x13: strcpy(pdesc,"NMI"); break; case 0x23: strcpy(pdesc,"Watchdog"); break; case 0x20: strcpy(pdesc,"OS Critical Stop"); break; default: #ifdef METACOMMAND p = get_sensor_type_desc(stype); if (p != NULL) { strncpy(pdesc,p,mylen); mystr[mylen-1] = 0; /*stringify*/ } #else sprintf(pdesc,"Other[%02x]",stype); #endif break; } if (pef_array[idx-1][4] == PEF_SEV_OK) strcat(pdesc," OK"); } return(pdesc); } #ifdef METACOMMAND int i_lan(int argc, char **argv) #else #ifdef WIN32 int __cdecl #else int #endif main(int argc, char **argv) #endif { int ret; PEF_RECORD PefRecord; LAN_RECORD LanRecord; int i, idx, j; int c; char *pstr; uchar bset; int ndest = 4; int idest; char mystr[80]; char fpefok = 1; uchar * pc; int sz; // progname = argv[0]; printf("%s ver %s \n",progname,progver); j = 0; freadonly = FLAG_INIT; idx = argc; /*getopt loop counter*/ /* available opt chars: y O Q + = ~ _ */ while ((c = getopt(argc, argv,"a:b:cdef:gh:i:j:klm:n:op:q:rstu:v:w:xy:z#::A:B:C:DEF:G:H:I:J:K:L:M:N:OP:Q:R:S:T:U:V:X:YZ:?")) != EOF) { switch(c) { case 'a': /* alert dest number (usu 1 thru 4) */ alertnum = atob(optarg); if (alertnum > alertmax) alertnum = 1; j++; break; case 'b': bAuth = htoi(optarg); j++; break; /*undocumented*/ case 'c': fcanonical = 1; bdelim = BDELIM; break; case 'd': fenable = 0; fdisable = 1; freadonly = 0; break; case 'e': fenable = 1; fdisable = 0; freadonly = 0; break; case 'f': i = atoi(optarg); /*set arp_ctl*/ if (i < 0 || i > 3) printf("Invalid ARP control %d\n",i); else { arp_ctl = i; fsetarp = 1; j++; } break; case 'l': fpefenable = 0; fenable = 2; fdisable = 0; freadonly = 0; break; case 'h': /* VLAN ID */ i = atoi(optarg); if (i > 4095) vlan_enable = 0; else { vlan_enable = 1; vlan_id = (ushort)i; } j++; break; case 'y': /* OEM LAN Failover enable/disable */ i = atoi(optarg); if (i < 0) printf("Failover(-y) parameter is negative\n"); else failover_enable = i; j++; break; case 'Q': /* VLAN Priority */ i = atoi(optarg); if (i > 7 || i < 0) vlan_enable = 0; else { vlan_enable = 1; vlan_prio = (uchar)i; } j++; break; case 'i': /* eth interface (ifname) */ fsetifn = 1; i = sizeof(ifname); if (strlen(optarg) > (uint)i) optarg[i] = 0; strcpy(ifname,optarg); if (fdebug) printf("ifname = %s\n",ifname); j++; break; case 'j': fCustomPEF = 1; /*custom 10 PEF bytes */ fpefenable = 1; /* PEF is implied here */ freadonly = 0; memset(custPEF,0,sizeof(custPEF)); custPEF[0] = htoi(&optarg[0]); /*action */ custPEF[1] = htoi(&optarg[2]); /*policy */ custPEF[2] = htoi(&optarg[4]); /*severity*/ custPEF[3] = htoi(&optarg[6]); /*genid1 */ custPEF[4] = htoi(&optarg[8]); /*genid2 */ custPEF[5] = htoi(&optarg[10]); /*sensor_type*/ custPEF[6] = htoi(&optarg[12]); /*sensor_num */ custPEF[7] = htoi(&optarg[14]); /*evt_trigger*/ custPEF[8] = htoi(&optarg[16]); /*data1offset*/ custPEF[9] = htoi(&optarg[18]); /*data1mask */ if (optarg[20] != 0) { /* optionally get 8 extra PEF entry bytes */ custPEF[10] = htoi(&optarg[20]); /*data1cmp1 */ custPEF[11] = htoi(&optarg[22]); /*data1cmp2 */ custPEF[12] = htoi(&optarg[24]); /*data2mask */ custPEF[13] = htoi(&optarg[26]); /*data2cmp1 */ custPEF[14] = htoi(&optarg[28]); /*data2cmp2 */ custPEF[15] = htoi(&optarg[30]); /*data3mask */ custPEF[16] = htoi(&optarg[32]); /*data3cmp1 */ custPEF[17] = htoi(&optarg[34]); /*data3cmp2 */ } j++; break; case 'k': fSetPEFOks = 1; j++; break; /*configure PEF OK rules */ case 'm': set_max_kcs_loops(atoi(optarg)); break; case 'n': /* number/index in PEF table to insert new entry */ fpefenable = 1; pefnum = atob(optarg); if (pefnum >= MAXPEF) { pefnum = MAXPEF - 1; fAdjustPefNum = 1; } else fUserPefNum = 1; j++; break; case 'o': fdisableSOL = 1; /*disable SOL only*/ fpefenable = 0; /*no change to PEF*/ freadonly = 0; break; case 'r': freadonly = 1; fenable = 0; break; case 's': fgetser = 1; break; case 't': ftestonly = 1; freadonly = 1; break; case 'v': /* user access privilege level */ i = atoi(optarg); if (valid_priv(i)) lan_access = i & 0x0f; else printf("Invalid privilege -v %d, using Admin\n",i); j++; break; case 'w': i = atoi(optarg); /*set grat arp interval, in #sec*/ if (i >= 0 && i < 256) arp_interval = i * 2; else printf("Invalid arp interval -w %d, skipping\n",i); break; case 'x': fdebug = 1; break; case 'z': flanstats = 1; break; case 'D': lan_dhcp = 1; j++; break; case 'O': flansecure = 1; j++; break; case 'I': /* My BMC IP Address */ fset_ip |= MYIP; atoip(rgmyip,optarg); j++; break; case 'M': /* My BMC MAC Address */ atomac(rgmymac,optarg); if (!MacIsValid(rgmymac)) printf("Invalid MAC for -M\n"); j++; break; case 'S': /* Subnet IP Address */ atoip(rgsubnet,optarg); j++; break; case 'G': /* Gateway IP Address */ fset_ip |= GWYIP; atoip(rggwyip,optarg); j++; break; case 'g': /* Secondary Gateway IP Address */ fset_ip |= GWYIP; atoip(rggwy2ip,optarg); j++; break; case 'H': /* Gateway MAC Address */ atomac(rggwymac,optarg); if (!MacIsValid(rggwymac)) printf("Invalid MAC for -H\n"); j++; break; case 'B': /* SOL Baud rate */ fnewbaud = 1; sol_baud = Str2Baud(optarg); j++; break; case 'A': /* Alert Dest IP Address */ fset_ip |= DESTIP; /* allow name or ip here via Get_Mac() ? */ atoip(rgdestip,optarg); fpefenable = 1; /* PEF is implied here */ j++; break; case 'X': /* Alert Dest MAC Address */ atomac(rgdestmac,optarg); if (!MacIsValid(rgdestmac)) printf("Invalid MAC for -X\n"); fpefenable = 1; /* PEF is implied here */ j++; break; case 'K': /* Kontron IPMI hostname */ i = sizeof(rghostname); /*usu 18*/ if (strlen(optarg) > (uint)i) optarg[i] = 0; strcpy(rghostname,optarg); j++; break; case 'C': /* Community String */ fsetcommunity = 1; i = sizeof(rgcommunity); /*usu 18*/ if (strlen(optarg) > (uint)i) optarg[i] = 0; strcpy(rgcommunity,optarg); fpefenable = 1; /* PEF is implied here */ j++; break; case 'u': /* username to set */ myuser = strdup_(optarg); /*remote username */ j++; break; case 'p': /* password to set */ fpassword = 1; if (strlen(optarg) > PSW_MAX) optarg[PSW_MAX] = 0; strcpy(passwordData,optarg); if (fdebug) printf("Password = %s\n",passwordData); /* Hide password from 'ps' */ memset(optarg, ' ', strlen(optarg)); j++; break; case 'q': case '#': usernum = atob(optarg); if (usernum > 15) usernum = 0; /*MAX_IPMI_USERS = 15*/ j++; break; case 'L': if (strcmp(optarg,"list") == 0) fshowchan = 1; lan_ch_parm = atob(optarg); if (lan_ch_parm > MAXCHAN) lan_ch_parm = PARM_INIT; /*invalid*/ break; case 'V': /* priv level */ fprivset = 1; case 'N': /* nodename */ case 'U': /* remote username */ case 'P': /* remote password */ case 'R': /* remote password */ case 'E': /* get password from IPMI_PASSWORD environment var */ case 'F': /* force driver type */ case 'T': /* auth type */ case 'J': /* cipher suite */ case 'Y': /* prompt for remote password */ case 'Z': /* set local MC address */ parse_lan_options(c,optarg,fdebug); break; default: printf("Usage: %s [-abcdefghijklmnopq#rstuvwxyzBDQK]\n",progname); printf(" \t [-a alertnum -i eth1 -n pefnum ]\n"); printf(" \t [-I ipadr -M macadr -S subnet ]\n"); printf(" \t [-G gwyip -H gwymac -L lan_channel_num]\n"); printf(" \t [-A alertip -X alertmac -C community ]\n"); printf(" \t [-g 2nd_gwyip -v priv -B sol_baud ]\n"); printf(" \t [-j 10_bytes_custom_pef -b authmask ]\n"); printf("where -c shows Canonical, simpler output format\n"); printf(" -d Disables BMC LAN & PEF\n"); printf(" -e Enables BMC LAN & PEF\n"); printf(" -f set ARP Control to 1=grat, 2=resp, 3=both\n"); printf(" -g secondary Gateway IP (-G=primary_gwy_ip)\n"); printf(" -h VLAN ID (>=4096 to disable)\n"); printf(" -j specify custom PEF rule (10 or 18 hex bytes)\n"); printf(" -k add PEF oK rules, if PEF enable\n"); printf(" -l Enables BMC LAN only, not PEF\n"); printf(" -o disable Only SOL\n"); printf(" -p password to set \n"); printf(" -q/-# User number of LAN username_to_set\n"); printf(" -r Read-only BMC LAN & PEF settings\n"); printf(" -s Show some Serial settings also \n"); printf(" -t Test if BMC LAN is already configured\n"); printf(" -u username to set \n"); printf(" -v access priVilege: 4=Admin,3=Operator,2=User\n"); printf(" -w set Grat ARP Interval to specified # seconds\n"); printf(" -x Show eXtra debug messages\n"); printf(" -y OEM LAN Failover (1=enable,0=disable if Intel)\n"); printf(" -z Show IPMI LAN statistics\n"); printf(" -B Baud for SerialOverLan (19.2K,115.2K,...)\n"); printf(" -D Use DHCP instead of static IP (-I for server)\n"); printf(" -K (Kontron) IPMI hostname to set\n"); printf(" -Q VLAN Priority (default =0)\n"); printf(" -O Force LAN security: no null user, cipher 0 off\n"); print_lan_opt_usage(); ret = ERR_USAGE; goto do_exit; } /*end switch*/ nopts++; } /*end while*/ if ((freadonly == FLAG_INIT) && (j > 0)) { /* got some options implying set, but no -e -l -d option specified. */ foptmsg = 1; /*show warning message later*/ freadonly = 1; /*assume read only*/ } fipmilan = is_remote(); if (fipmilan && !fprivset) parse_lan_options('V',"4",0); /*even if freadonly request admin*/ if ((fsetarp == 0) && ostype == OS_WINDOWS) arp_ctl = 0x03; /*grat arp & arp resp enabled */ ret = GetDeviceID( &LanRecord); if (ret != 0) { goto do_exit; } else { /* success */ uchar ipmi_maj, ipmi_min; ipmi_maj = LanRecord.data[4] & 0x0f; ipmi_min = LanRecord.data[4] >> 4; show_devid( LanRecord.data[2], LanRecord.data[3], ipmi_maj, ipmi_min); if (ipmi_maj == 0) fIPMI10 = 1; else if (ipmi_maj == 1 && ipmi_min < 5) fIPMI10 = 1; else fIPMI10 = 0; /* >= IPMI 1.5 is ok */ if (ipmi_maj >= 2) fIPMI20 = 1; if (fIPMI20) show_users = 5; else show_users = 3; if (fIPMI10) { printf("This IPMI v%d.%d system does not support PEF records.\n", ipmi_maj,ipmi_min); /* Wont handle PEF, but continue and look for BMC LAN anyway */ // fIPMI10 = 1; // ipmi_close_(); // exit(1); } prod_id = LanRecord.data[9] + (LanRecord.data[10] << 8); vend_id = LanRecord.data[6] + (LanRecord.data[7] << 8) + (LanRecord.data[8] << 16); /* check Device ID response for Manufacturer ID = 0x0322 (NSC) */ if (vend_id == VENDOR_NSC) { /* NSC = 0x000322 */ fmBMC = 1; /*NSC miniBMC*/ if (pefnum == 12) pefnum = 10; /* change CritStop pefnum to 0x0a */ pefdesc = &pefdesc2[0]; /*mini-BMC PEF*/ pefmax = 30; fsharedMAC = 1; /* shared MAC with OS */ } else if (vend_id == VENDOR_LMC) { /* LMC (on SuperMicro) = 0x000878 */ pefdesc = NULL; /* unknown, see PefDesc() */ if (pefnum == 12) pefnum = 15; /* change CritStop pefnum */ pefmax = 16; fsharedMAC = 0; /* not-shared BMC LAN port */ } else if (vend_id == VENDOR_INTEL) { /* Intel = 0x000157 */ pefdesc = &pefdesc1[0]; /*default Intel PEF*/ pefmax = 20; /*default Intel PEF*/ switch(prod_id) { case 0x4311: /* Intel NSI2U w SE7520JR23 */ fmBMC = 1; /* Intel miniBMC*/ if (pefnum == 12) pefnum = 14; /* change CritStop pefnum */ pefdesc = &pefdesc2[0]; /*mini-BMC PEF*/ pefmax = 30; fsharedMAC = 1; /* shared-MAC BMC LAN port, same MAC */ break; case 0x0022: /* Intel TIGI2U w SE7520JR23 +IMM*/ fsharedMAC = 1; /* shared-MAC BMC LAN port, same MAC */ gcm_ch = 3; /* IMM GCM port, dedicated MAC */ show_users = 4; break; case 0x000C: /*TSRLT2*/ case 0x001B: /*TIGPR2U*/ /* fmBMC=0; Intel Sahalee BMC*/ fsharedMAC = 1; /* shared-MAC BMC LAN port, same MAC */ break; case 0x0026: /*S5000 Bridgeport*/ case 0x0028: /*S5000PAL Alcolu*/ case 0x0029: /*S5000PSL StarLake*/ case 0x0811: /*S5000PHB TIGW1U */ /* fmBMC=0; Intel Sahalee ESB2 BMC*/ fsharedMAC = 0; /* not-shared BMC LAN port, separate MAC */ gcm_ch = 3; parm7 = &iparm7[0]; /*TTL=30*/ break; case 0x003E: /*NSN2U or CG2100 Urbanna*/ fiBMC = 1; /* Intel iBMC */ fsharedMAC = 0; /* not-shared BMC LAN port, separate MAC */ // gcm_ch = 3; parm7 = &iparm7[0]; /*TTL=30*/ if (fsetarp == 0) arp_ctl = 0x02; /*grat arp disabled, arp resp enabled */ arp_interval = 0x00; /*0 sec, since grat arp disabled */ sol_accum[0] = 0x0c; /*Intel defaults*/ sol_accum[1] = 0x60; /*Intel defaults*/ sol_retry[0] = 0x07; /*Intel defaults*/ sol_retry[1] = 0x32; /*Intel defaults*/ set_max_kcs_loops(URNLOOPS); /*longer for SetLan cmds (default 300)*/ break; case 0x0107: /* Intel Caneland*/ fsharedMAC = 0; /* not-shared BMC LAN port, separate MAC */ gcm_ch = 3; break; case 0x0100: /*Tiger2 ia64*/ /* for ia64 set chan_pefon, chan_pefoff accordingly*/ chan_pefon = CHAN_ACC_PEFON64; chan_pefoff = CHAN_ACC_PEFOFF64; /* fall through */ default: /* else other Intel */ /* fmBMC = 0; * Intel Sahalee BMC*/ if (fIPMI20) fsharedMAC = 0; /* recent, not-shared BMC MAC */ else fsharedMAC = 1; /* usu IPMI 1.x has shared BMC MAC */ break; } /*end switch*/ if (is_romley(vend_id,prod_id)) { fRomley = 1; fiBMC = 1; /* Intel iBMC */ fsharedMAC = 0; /* not-shared BMC LAN port, separate MAC */ set_max_kcs_loops(URNLOOPS); /*longer for SetLan (default 300)*/ fipv6 = 1; if (fsetarp == 0) arp_ctl = 0x03; /*default to both for Romley*/ } } else { /* else other vendors */ if (fIPMI20) fsharedMAC = 0; /* recent, not-shared BMC MAC */ else fsharedMAC = 1; /* usu IPMI 1.x has shared BMC MAC */ pefdesc = NULL; /* unknown, see PefDesc() */ if (pefnum == 12) pefnum = 15; /* change CritStop pefnum to 15? */ pefmax = 20; if (!fUserPefNum) fAdjustPefNum = 1; } if (fmBMC) show_users = 1; /* mBMC doesn't support more than 1 user */ } if (fshowchan) { ret = show_channels(); exit(ret); } ret = GetPefCapabilities(&bset); if ((ret == 0) && (bset <= MAXPEF)) pefmax = bset; /* Get the BMC LAN channel & match it to an OS eth if. */ i = GetBmcEthDevice(lan_ch_parm); if (i == -2) { /* no lan channels found (see lan_ch) */ if (lan_ch_parm == PARM_INIT) printf("This system does not support IPMI LAN channels.\n"); else /*specified a LAN channel*/ printf("BMC channel %d does not support IPMI LAN.\n",lan_ch_parm); ret = LAN_ERR_NOTSUPPORT; goto do_exit; } else if (i < 0) { /* mac not found, use platform defaults */ i = 0; /* default to eth0, lan_ch set already. */ if (vend_id == VENDOR_INTEL) { if ((prod_id == 0x001B) || (prod_id == 0x000c)) { /* Intel TIGPR2U or TSRLT2 defaults are special */ if (lan_ch_parm == 6) { i = 0; lan_ch = 6; } else { i = 1; lan_ch = 7; } ser_ch = 1; } } } if ((i == gcm_ch) && (gcm_ch != PARM_INIT) && (lan_ch_parm == PARM_INIT)) { /* Has a GCM, defaulted to it, and user didn't specify -L */ /* Need this to avoid picking channel 3, the IMM/RMM GCM channel. */ lan_ch = 1; /*default BMC LAN channel*/ // i = 0; /*default eth0 (was eth1) */ } if (fsetifn == 0) { /*not user specified, use the detected one*/ // if (lan_ch == gcm_ch) strcpy(ifname,"gcm"); sprintf(ifname,"%s%d",ifpattn,i); /*eth%d*/ } if (fdebug) printf("lan_ch = %d, ifname = %s\n",lan_ch,ifname); /* set the lan_user appropriately */ if (myuser == NULL) { /* if no -u param */ if (ipmi_reserved_user(vend_id, 1)) lan_user = 2; else if (flansecure) lan_user = 2; else lan_user = 1; /*use default null user */ } else if (usernum != 0) lan_user = usernum; /*use -q specified usernum*/ /* else use default lan_user (=2) if -u and not -q */ if (ftestonly) { /*test only if BMC LAN is configured or not */ /* TODO: test gcm also, if present */ ret = GetLanEntry(4, 0, &LanRecord); /*ip addr src*/ if (ret == 0) { if ((LanRecord.data[0] == SRC_BIOS) || (LanRecord.data[0] == SRC_DHCP)) ret = 0; /* DHCP, so ok */ else { /*static IP*/ ret = GetLanEntry(3, 0, &LanRecord); /* ip address */ if (ret == 0) { if (!IpIsValid(LanRecord.data)) { printf("invalid BMC IP address\n"); ret = 1; /* invalid ip */ } else ret = GetLanEntry(12, 0, &LanRecord); /*gateway ip*/ if (ret == 0) { if (!IpIsValid(LanRecord.data)) { printf("invalid gateway ip\n"); ret = 2; /*invalid gwy ip*/ } else ret = GetLanEntry(13, 0, &LanRecord); if (ret == 0) { if (!MacIsValid(&LanRecord.data[0])) { printf("invalid gateway mac\n"); ret = 3; /*invalid gwy mac */ } } } } } } /*endif GetLanEntry ok*/ if (ret == 0) printf("BMC LAN already configured\n"); else printf("BMC LAN not configured\n"); goto do_exit; } /*endif ftestonly*/ memset(SessInfo,0,sizeof(SessInfo)); ret = GetSessionInfo(SessInfo,sizeof(SessInfo)); // rlen = sizeof(SessInfo)); ret = get_session_info(0,0,SessInfo,&rlen); if (fdebug) printf("GetSessionInfo ret=%d, data: %02x %02x %02x %02x \n", ret,SessInfo[0],SessInfo[1],SessInfo[2],SessInfo[3]); if (!freadonly && fipmilan) { /* setting LAN params, and using IPMI LAN */ if (SessInfo[2] > 1) { /* another session is active also */ printf("Another session is also active, cannot change IPMI LAN settings now.\n"); ret = ERR_NOT_ALLOWED; goto do_exit; } } if (!fIPMI10) { if (fcanonical) { /* canonical/simple output */ ret = GetPefEntry(0x01, 0,(PEF_RECORD *)&LanRecord); if (ret != 0) ndest = 0; else { /*success*/ j = LanRecord.data[0]; mystr[0] = 0; if (j == 0) strcat(mystr,"none "); else { if (j & 0x01) strcat(mystr,"PEFenable "); if (j & 0x02) strcat(mystr,"DoEventMsgs "); if (j & 0x04) strcat(mystr,"Delay "); if (j & 0x08) strcat(mystr,"AlertDelay "); } printf("PEF Control %s%c %s\n",pspace4,bdelim,mystr); } } else { /* normal/full output */ ret = GetPefEntry(0x01, 0,(PEF_RECORD *)&LanRecord); if (ret == 0 && (LanRecord.data[0] != 0)) { fpefok = 1; bmcpefctl = LanRecord.data[0]; } else { /* skip PEF rules/params if disabled */ printf("PEF Control %s%c %s\n",pspace4,bdelim,"none "); ndest = 0; fpefok = 0; } if (fpefok) { printf("%s, GetPefEntry ...\n",progname); for (idx = 1; idx <= pefmax; idx++) { ret = GetPefEntry( 0x06, (ushort)idx, &PefRecord); if (ret == 0) { // Show the PEF record char *pa; pc = (uchar *)&PefRecord; sz = 21; // sizeof(PEF_RECORD) = 21 if (PefRecord.sensor_type == 0) { if (idx <= pefnum) printf("PEFilter(%02d): empty\n",idx); memcpy(pef_array[idx-1], &PefRecord, sz); if (fAdjustPefNum) pefnum = (char)idx; } else { memcpy(pef_array[idx-1], &PefRecord, sz); if (PefRecord.fconfig & 0x80) pc = "enabled"; else pc = "disabled"; i = PefRecord.rec_id; switch(PefRecord.action) { case 0x01: pa = "alert"; break; case 0x02: pa = "poweroff"; break; case 0x04: pa = "reset"; break; case 0x08: pa = "powercycle"; break; case 0x10: pa = "OEMaction"; break; case 0x20: pa = "NMI"; break; default: pa = "no action"; } printf("PEFilter(%02d): %02x %s event - %s for %s\n", idx, PefRecord.sensor_type, PefDesc(i,PefRecord.sensor_type), pc,pa); } if (fdebug) { /* show raw PEFilter record */ pc = &PefRecord.rec_id; printf("raw PEF(%.2d): ",pc[0]); for (i = 0; i < sz; i++) printf("%02x ",pc[i]); printf("\n"); } } else { printf("GetPefEntry(%d), ret = %d\n",idx,ret); if (ret == 0xC1) { /*PEF is not supported, so skip the rest. */ fpefok = 0; ndest = 0; /* if no PEF, no alerts & no alert dest */ break; } } } } /*endif fpefok*/ if (fpefok) { if (fdebug) ShowPef(); ret = GetPefEntry(0x01, 0,(PEF_RECORD *)&LanRecord); if (ret == 0) { j = LanRecord.data[0]; mystr[0] = 0; if (j & 0x01) strcat(mystr,"PEFenable "); if (j & 0x02) strcat(mystr,"DoEventMsgs "); if (j & 0x04) strcat(mystr,"Delay "); if (j & 0x08) strcat(mystr,"AlertDelay "); printf("PEF Control: %02x : %s\n",j, mystr); } ret = GetPefEntry(0x02, 0,(PEF_RECORD *)&LanRecord); if (ret == 0) { j = LanRecord.data[0]; mystr[0] = 0; if (j & 0x01) strcat(mystr,"Alert "); if (j & 0x02) strcat(mystr,"PwrDn "); if (j & 0x04) strcat(mystr,"Reset "); if (j & 0x08) strcat(mystr,"PwrCyc "); if (j & 0x10) strcat(mystr,"OEM "); if (j & 0x20) strcat(mystr,"DiagInt "); printf("PEF Actions: %02x : %s\n",j, mystr); } ret = GetPefEntry(0x03, 0,(PEF_RECORD *)&LanRecord); if (ret == 0) printf("PEF Startup Delay: %02x : %d sec\n", LanRecord.data[0],LanRecord.data[0]); if (!fmBMC) { ret = GetPefEntry(0x04, 0,(PEF_RECORD *)&LanRecord); if (ret == 0) printf("PEF Alert Startup Delay: %02x: %d sec\n", LanRecord.data[0],LanRecord.data[0]); /* fmBMC gets cc=0x80 here */ } /* note that ndest should be read from lan param 17 below. */ for (i = 1; i <= ndest; i++) { ret = GetPefEntry(0x09, (ushort)i,(PEF_RECORD *)&LanRecord); if (ret == 0) { mystr[0] = 0; j = LanRecord.data[2]; if (LanRecord.data[1] & 0x08) { sprintf(mystr,"Chan[%d] Dest[%d] ",((j & 0xf0) >> 4),(j & 0x0f)); strcat(mystr,"Enabled "); } else strcpy(mystr,"Disabled "); printf("PEF Alert Policy[%d]: %02x %02x %02x %02x : %s\n",i, LanRecord.data[0], LanRecord.data[1], LanRecord.data[2], LanRecord.data[3],mystr); } } /*endfor ndest*/ } /*endif fpefok*/ } /*endif not canonical*/ if (fpefenable && !freadonly) { /* fenable or fdisable */ if (fSetPEFOks) pefadd = 5; else pefadd = 2; sz = (pefnum - 1) + pefadd + fCustomPEF; printf("\n%s, SetPefEntry(1-%d) ...\n",progname,sz); if (fdebug) printf("pefnum = %d, pefmax = %d\n",pefnum,pefmax); for (idx = 1; idx <= pefmax; idx++) { // Set & Enable all PEF records memset(&PefRecord.rec_id,0,sizeof(PEF_RECORD)); PefRecord.rec_id = (uchar)idx; /* next record, or user-specified */ if (idx < pefnum) { /* pefnum defaults to 12.(0x0c) */ if (pef_array[idx-1][7] == 0) /*empty pef record, set to default*/ memcpy(&PefRecord.rec_id,pef_defaults[idx-1],sizeof(PEF_RECORD)); else { /* set config however it was previously */ memcpy(&PefRecord.rec_id,pef_array[idx-1],sizeof(PEF_RECORD)); if (PefRecord.severity == 0) PefRecord.severity = pef_defaults[idx-1][4]; } } else if ((idx == pefnum) && /* new OS Crit Stop entry */ (PefRecord.sensor_type == 0)) { // Set PEF values for 0x20, OS Critical Stop event PefRecord.severity = PEF_SEV_CRIT; PefRecord.genid1 = 0xff; PefRecord.genid2 = 0xff; PefRecord.sensor_type = 0x20; /* OS Critical Stop */ PefRecord.sensor_no = 0xff; PefRecord.event_trigger = 0x6f; PefRecord.data1 = 0xff; PefRecord.mask1 = 0x00; } else if ((idx == pefnum+1) && /* new Power Redundancy entry */ (PefRecord.sensor_type == 0)) { // Set PEF values for 0x09/0x02/0x0b/0x41, Power Redundancy Lost PefRecord.severity = PEF_SEV_WARN; PefRecord.genid1 = 0xff; PefRecord.genid2 = 0xff; PefRecord.sensor_type = 0x09; /* Power Unit */ PefRecord.sensor_no = 0xff; /* usu 01 or 02 */ PefRecord.event_trigger = 0x0b; /* event trigger */ PefRecord.data1 = 0x02; /* 02 -> 41=Redundancy Lost */ PefRecord.mask1 = 0x00; } else if (fSetPEFOks && idx == (pefnum+2)) { PefRecord.severity = PEF_SEV_OK; PefRecord.genid1 = 0xff; PefRecord.genid2 = 0xff; PefRecord.sensor_type = 0x09; /* Power Unit, Redund OK */ PefRecord.sensor_no = 0xff; /* usu 01 or 02 */ PefRecord.event_trigger = 0x0b; /* event trigger */ PefRecord.data1 = 0x01; /* 01 -> 40=Redundancy OK */ PefRecord.mask1 = 0x00; } else if (fSetPEFOks && idx == (pefnum+3)) { PefRecord.severity = PEF_SEV_OK; PefRecord.genid1 = 0xff; PefRecord.genid2 = 0xff; PefRecord.sensor_type = 0x01; /* Temp OK */ PefRecord.sensor_no = 0xff; /* usu 01 or 02 */ PefRecord.event_trigger = 0x81; /* event trigger */ PefRecord.data1 = 0x95; /* 95 -> 50(NC),52(Crit) match */ PefRecord.mask1 = 0x0a; } else if (fSetPEFOks && idx == (pefnum+4)) { PefRecord.severity = PEF_SEV_OK; PefRecord.genid1 = 0xff; PefRecord.genid2 = 0xff; PefRecord.sensor_type = 0x02; /* Voltage OK */ PefRecord.sensor_no = 0xff; /* usu 01 or 02 */ PefRecord.event_trigger = 0x81; /* event trigger */ PefRecord.data1 = 0x95; /* 95 -> 50(NC),52(Crit) match */ PefRecord.mask1 = 0x0a; } else if (fCustomPEF && idx == (pefnum+pefadd)) { /* user entered 10 or 18 PEF entry bytes */ PefRecord.action = custPEF[0]; PefRecord.policy = custPEF[1]; PefRecord.severity = custPEF[2]; PefRecord.genid1 = custPEF[3]; PefRecord.genid2 = custPEF[4]; PefRecord.sensor_type = custPEF[5]; PefRecord.sensor_no = custPEF[6]; PefRecord.event_trigger = custPEF[7]; PefRecord.data1 = custPEF[8]; PefRecord.mask1 = custPEF[9]; memcpy(&PefRecord.action,custPEF,18); } else { memcpy(&PefRecord.rec_id,pef_array[idx-1],sizeof(PEF_RECORD)); if (PefRecord.sensor_type == 0) continue; /* if reserved, skip it */ } if (fdebug && (PefRecord.rec_id != idx)) { /* memcpy from pef_defaults or pef_array clobbered rec_id */ printf("Warning: SetPef idx=%d, rec_id=%d\n",idx,PefRecord.rec_id); PefRecord.rec_id = (uchar)idx; /*fix it*/ } if (fdisable) { /* Disable all PEF rules */ if (idx >= pefnum) PefRecord.fconfig = 0x00; /*disabled, software*/ else PefRecord.fconfig = 0x40; /*disabled, preset */ PefRecord.action = 0x00; PefRecord.policy = 0x00; } else { /*fenable*/ if (PefRecord.sensor_type != 0) { /* not an empty PEF entry */ /* Enable all non-empty PEF rules */ if (fCustomPEF && (idx == (pefnum+pefadd))) { PefRecord.action = custPEF[0]; PefRecord.policy = custPEF[1]; } else { PefRecord.action = 0x01; /*Alert*/ PefRecord.policy = 0x01; /*see Alert Policy #1*/ } if (idx < pefnum) { /* special handling for presets, 1 thru 11 */ PefRecord.fconfig = 0x80; /* enabled, software */ ret = SetPefEntry(&PefRecord); if (fdebug) printf("SetPefEntry(%d/80) ret=%d\n",PefRecord.rec_id,ret); // if (ret != 0) { nerrs++; lasterr = ret; } // else ngood++; PefRecord.fconfig = 0xC0; /* enabled, preset */ } else { PefRecord.fconfig = 0x80; /* enabled, software */ } } /*endif not empty*/ } { // Show the new PEF record before setting it. pc = (uchar *)&PefRecord; sz = 21; printf("PEFilter(%d): ",PefRecord.rec_id); for (i = 0; i < sz; i++) printf("%02x ",pc[i]); printf("\n"); } ret = SetPefEntry(&PefRecord); if (fdebug) printf("SetPefEntry(%d) ret = %d\n", PefRecord.rec_id,ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } /*end for*/ } } /*end if not fIPMI10*/ if (!fcanonical) printf("\n%s, GetLanEntry for channel %d ...\n",progname,lan_ch); idest = 1; for (idx = 0; idx < NLAN; idx++) { int ival; if (fcanonical && (canon_param[idx] == 0)) continue; if (idx == 8 || idx == 9) continue; /* not implemented */ ival = lanparams[idx].cmd; if (ival >= 96 && ival <= 98) continue; /* not implemented */ if (ival >= 102 && ival <= 108) { /*custom IPv6 parameters*/ if (fipv6 == 0) continue; /*skip these*/ } if (ival == 194 && vend_id == VENDOR_KONTRON) { /*oem hostname parm*/ lanparams[idx].sz = 36; strcpy(lanparams[idx].desc,"IPMI Hostname"); } else if (ival >= 192 && ival <= 194) { /*custom DHCP parameters*/ if (vend_id != VENDOR_INTEL) continue; if (fmBMC || fiBMC || fcanonical) continue; /*skip these*/ } if (ival >= 20 && ival <= 25) { if (!fIPMI20) continue; /*VLAN params 20-25, fIPMI20 only/opt*/ } if ((ndest == 0) && (ival >= 18 && ival <= 19)) continue; /*skip dest*/ if (ival == 11) { /*grat arp interval*/ if (vend_id == VENDOR_SUPERMICROX) continue; if (vend_id == VENDOR_SUPERMICRO) continue; } if (ival == 14 || ival == 15) { /*secondary gateway is optional*/ if (vend_id == VENDOR_KONTRON) continue; } if (ival == 201) { /*Get Channel Access*/ ret = ShowChanAcc(lan_ch); } else { if (ival == 18 || ival == 19) { /*dest params*/ if (ndest == 0) continue; /*skip if ndest==0 */ bset = (uchar)idest; /* dest id = 1 thru n */ } else bset = 0; ret = GetLanEntry((uchar)ival, bset, &LanRecord); } if (ret == 0) { // Show the LAN record pc = (uchar *)&LanRecord; sz = lanparams[idx].sz; if (ival == 18) { /*skip if invalid dest type param*/ if ((idest > 1) && (pc[2] == 0)) { idest = 1; continue; } } else if (ival == 19) { /*skip if invalid dest addr param*/ if ((idest > 1) && !IpIsValid(&pc[3])) { idest = 1; continue; } } if (ival == 201) ; /* did it above */ else { if (fcanonical) { if ((ival == 19) && (idest > 1)) ; /*skip it*/ else { j = strlen_(lanparams[idx].desc); // (ival < 7) || (ival == 19) || ival == 102) if (j <= 12) pstr = pspace3; else pstr = pspace2; printf("Channel %d %s %s%c ",lan_ch, lanparams[idx].desc,pstr,bdelim); } } else printf("Lan Param(%d) %s: ",ival,lanparams[idx].desc); } if (ival == 1) { authmask = pc[0]; /* auth type support mask */ /* if (fmBMC) authmask is usually 0x15, else 0x14 */ } else if (ival == 3) { if (IpIsValid(pc)) memcpy(bmcmyip,pc,4); } else if (ival == 5) { if (MacIsValid(pc)) memcpy(bmcmymac,pc,MAC_LEN); } else if (ival == 6) { if (SubnetIsValid(pc)) memcpy(bmcsubnet,pc,4); /* else if invalid, leave default as 255.255.255.0 */ //} else if (ival == 7) { // if (pc[0] >= 30) memcpy(bparm7,pc,3); } else if (ival == 17) { /* num dest */ ndest = pc[0]; /* save the number of destinations */ } else if (ival == 19) { /* dest addr */ if (IpIsValid(&pc[3])) memcpy(bmcdestip,&pc[3],4); if (MacIsValid(&pc[7])) memcpy(bmcdestmac,&pc[7],MAC_LEN); } else if (ival == 22) { /*Cipher Suite Support*/ nciphers = pc[0]; } /* now start to display data */ if (ival == 16) { printf("%s \n",pc); /* string */ } else if (ival == 194 && vend_id == VENDOR_KONTRON) { printf("%s \n",pc); /* string */ } else if (ival == 201) { ; /* did it above */ } else { /* print results for all other ival's */ pstr = ""; /*interpreted meaning*/ if (fcanonical) { switch(ival) { case 4: /*param 4, ip src*/ if (pc[0] == SRC_STATIC) pstr = "Static"; /*0x01*/ else if (pc[0] == SRC_DHCP) pstr = "DHCP"; /*0x02*/ else if (pc[0] == SRC_BIOS) pstr = "BIOS"; /*0x03*/ else pstr = "Other"; printf("%s\n",pstr); break; case 5: /*param 5, mac addr*/ case 13: /*param 6, def gwy mac*/ printf("%02x:%02x:%02x:%02x:%02x:%02x\n", pc[0], pc[1], pc[2], pc[3], pc[4], pc[5]); break; case 3: /*param 4, ip address*/ case 6: /*param 6, subnet mask*/ case 12: /*param 12, def gwy ip*/ case 14: /*param 14, sec gwy ip*/ case 192: /*param 192, DHCP svr ip*/ printf("%d.%d.%d.%d\n",pc[0], pc[1], pc[2], pc[3]); break; case 19: /*param 19, dest address*/ if (idest == 1) { printf("IP=%d.%d.%d.%d " "MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", pc[3], pc[4], pc[5], pc[6], pc[7], pc[8], pc[9], pc[10], pc[11], pc[12]); } break; case 102: /*param 102, IPv6 enable*/ if (pc[0] == 0x01) printf("enabled\n"); else printf("disabled\n"); break; default: printf("%02x \n",pc[0]); break; } } else { /*not canonical */ if (ival == 3 || ival == 6 || ival == 12 || ival == 14 || ival == 192) { printf("%d.%d.%d.%d",pc[0], pc[1], pc[2], pc[3]); } else if (ival == 23) { /*Cipher Suites*/ for (i = 1; i <= nciphers; i++) { if (pc[i] == 0) ncipher0 = pc[i]; printf("%2d ",pc[i]); } } else if (ival == 24) { /*Cipher Suite Privi Levels*/ j = 0; for (i = 1; i < 9; i++) { char c1, c2; char *p; p = parse_priv((pc[i] & 0x0f)); c1 = p[0]; p = parse_priv((pc[i] & 0xf0) >> 4); c2 = p[0]; rgciphers[j++] = (pc[i] & 0x0f); rgciphers[j++] = ((pc[i] & 0xf0) >> 4); if ((i*2) >= nciphers) c2 = ' '; printf(" %c %c ",c1,c2); if ((i*2) > nciphers) break; } } else for (i = 0; i < sz; i++) { /* print in hex, decimal, or string, based on ival */ if (ival == 1) { /* Auth type support */ pstr = &mystr[0]; getauthstr(authmask,pstr); printf("%02x ",authmask); } else if (ival == 4) { /* IP addr source */ if (pc[i] == SRC_STATIC) pstr = "Static"; /*0x01*/ else if (pc[i] == SRC_DHCP) pstr = "DHCP"; /*0x02*/ else if (pc[i] == SRC_BIOS) pstr = "BIOS"; /*0x03*/ else pstr = "Other"; printf("%02x ",pc[i]); } else if (ival == 10) { /* grat ARP */ mystr[0] = 0; if (pc[i] == 0) strcat(mystr,"ARP disabled "); else if (pc[i] & 0x01) strcat(mystr,"Grat-ARP enabled"); else strcat(mystr,"Grat-ARP disabled"); if (pc[i] & 0x02) strcat(mystr,", ARP-resp enabled"); pstr = &mystr[0]; printf("%02x ",pc[i]); } else if (ival == 11) { /* grat ARP interval */ float f; f = (float)pc[i] / (float)2; /*500msec increments*/ sprintf(mystr,"%.1f sec",f); pstr = &mystr[0]; printf("%02x ",pc[i]); } else if (ival == 19) { /* dest addr */ if (i > 2 && i < 7) { char *sepstr; if (i == 3) printf("["); if (i == 6) sepstr = "] "; else if (i >=3 && i < 6) sepstr = "."; else sepstr = " "; printf("%d%s",pc[i],sepstr); /* IP address in dec */ } else printf("%02x ",pc[i]); /* show mac/etc. in hex */ } else printf("%02x ",pc[i]); /* show in hex */ } /*end for*/ if (ival == 2) { /*Auth type enables*/ pstr = &mystr[0]; i = 0; if (lan_ch > 0) i = lan_ch - 1; getauthstr(pc[i],pstr); } if (pstr[0] != 0) printf(": %s\n",pstr); else printf("\n"); } /*end-else not canonical*/ } /*end-else others*/ if (ival == 18 || ival == 19) { if (idest < ndest) { idest++; idx--; /* repeat this param*/ } else idest = 1; } } else { /* ret != 0 */ if (ival >= 20 && ival <= 25) { /*if errors, optional*/ if (fdebug) printf("GetLanEntry(%d), ret = %d\n",ival,ret); } else printf("GetLanEntry(%d), ret = %d\n",ival,ret); if (ival == 17) ndest = 0; /*error getting num dest*/ } } /*end for*/ if (fRomley) { /*get LAN Failover param*/ uchar b; ret = lan_failover_intel(0xFF,(uchar *)&b); if (ret != 0) printf("Intel Lan Failover, ret = %d\n",ret); else { if (b == 1) pstr = "enabled"; else pstr = "disabled"; if (fcanonical) printf("Intel Lan Failover %s%c %s\n", pspace3, bdelim,pstr); else printf("Intel Lan Failover %s%c %02x %c %s\n", pspace2, bdelim,b,bdelim,pstr); } } if (vend_id == VENDOR_SUPERMICROX || vend_id == VENDOR_SUPERMICRO) { ret = oem_supermicro_get_lan_port(&bset); if (ret == 0) { pstr = oem_supermicro_lan_port_string(bset); if (fcanonical) printf("SuperMicro Lan Interface %s%c %s\n", pspace2, bdelim,pstr); else printf("SuperMicro Lan Interface %c %02x %c %s\n", bdelim,bset,bdelim,pstr); } else { if (fdebug) printf("oem_supermicro_get_lan_port error %d\n",ret); ret = 0; /*may not be supported on all smc plaforms*/ } } // if (fmBMC) lan_access = 0x04; /*Admin*/ // else lan_access = 0x04; /*Admin*/ if (!fIPMI10) { /* Get SOL params */ ret = GetSerialOverLan(lan_ch,0,0); if (ret != 0) printf("GetSOL error %d\n",ret); } for (i = 1; i <= show_users; i++) GetUser((uchar)i); if (fgetser && !fcanonical) { printf("\n%s, GetSerEntry ...\n",progname); if (fmBMC) /* mBMC doesn't support serial */ printf("No serial channel support on this platform\n"); else for (idx = 0; idx < NSER; idx++) { int ival; // if (idx == 9) continue; /* not implemented */ ival = serparams[idx].cmd; if (ival == 201) { ret = GetChanAcc(ser_ch, 0x40, &LanRecord); } else { ret = GetSerEntry((uchar)ival, &LanRecord); } if (ret == 0) { // Show the SER record pc = (uchar *)&LanRecord; sz = serparams[idx].sz; printf("Serial Param(%d) %s: ",ival,serparams[idx].desc); if (idx == 10) { /* modem init string */ pc[sz] = 0; printf("%02x %s\n",pc[0],&pc[1]); } else if ((idx >= 11 && idx <= 13) || idx == 15) { /* strings */ printf("%s\n",pc); } else { for (i = 0; i < sz; i++) { printf("%02x ",pc[i]); /* show in hex */ } printf("\n"); } /*end else*/ } } /*end for*/ } /*endif fgetser*/ if (!freadonly) /* Set IPMI LAN enable/disable params. */ { if (fipmilan) /* Sets not valid via ipmi_lan if same channel. */ printf("\nWarning: Setting LAN %d params while using a LAN channel.\n", lan_ch); { if (fenable && (fsharedMAC==0) && !lan_dhcp) { /* must have an IP from -I option */ if (!IpIsValid(rgmyip)) { /* if not user-specified */ if (IpIsValid(bmcmyip)) { memcpy(rgmyip,bmcmyip,4); if (fdebug) printf("Using current IP %d.%d.%d.%d\n", bmcmyip[0], bmcmyip[1], bmcmyip[2], bmcmyip[3]); } else { printf("\nNot shared BMC LAN, must specify a unique " "IP address via -I\n"); ret = ERR_BAD_PARAM; goto do_exit; } } } /* Set LAN parameters. fenable or fdisable */ printf("\n%s, SetLanEntry for channel %d ...\n",progname,lan_ch); /* use ifname to resolve MAC addresses below */ if (fdisable) { if (!fIPMI10) { ret = DisablePef(alertnum); printf("DisablePef, ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } if (lan_user != 0) { j = DisableUser(lan_user); /*disable this lan user*/ printf("DisableUser(%d), ret = %d\n",lan_user,j); if (j != 0) { nerrs++; lasterr = j; } else ngood++; } LanRecord.data[0] = 0x01; /* static IP address source */ ret = SetLanEntry(4, &LanRecord, 1); printf("SetLanEntry(4), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; /* clear the BMC IP address */ memset(&LanRecord,0,4); ret = SetLanEntry(3, &LanRecord, 4); printf("SetLanEntry(3), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; /* clear the gateway IP address */ memset(&LanRecord,0,4); ret = SetLanEntry(12, &LanRecord, 4); printf("SetLanEntry(12), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; /* clear the gateway MAC address */ memset(&LanRecord,0,6); ret = SetLanEntry(13, &LanRecord, 6); printf("SetLanEntry(13), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } else if (fdisableSOL) { ret = SetupSerialOverLan(0); /*disable*/ SELprintf("SetupSerialOverLan: ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } else { /*fenable*/ uchar chanctl; if (bmcpefctl != 0) chanctl = chan_pefon; /*previously on*/ else chanctl = chan_pefoff; ret = SetChanAcc(lan_ch, 0x80, chanctl); if (fdebug) printf("SetChanAcc(lan/active), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; ret = SetChanAcc(lan_ch, 0x40, chanctl); if (fdebug) printf("SetChanAcc(lan/nonvol), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; if (flansecure) { j = DisableUser(0); /*disable the default null user*/ printf("DisableUser(0), ret = %d\n",j); } ret = SetUser(lan_user,myuser,passwordData); printf("SetUser(%d), ret = %d\n",lan_user,ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } if (fdisable && (vend_id == VENDOR_SUPERMICROX || vend_id == VENDOR_SUPERMICRO) ) { failover_enable = 0; /*dedicated*/ ret = oem_supermicro_set_lan_port(failover_enable); printf("Set SuperMicro Lan port to %s, ret = %d\n", oem_supermicro_lan_port_string(failover_enable),ret); if (ret != 0) { nerrs++; lasterr = ret; } } if (fdisable || fdisableSOL) { // if (nerrs > 0) printf("Warning: %d errors occurred\n",nerrs); goto do_exit; } if (authmask == 0) authmask = 0x17; /*if none from GetLanEntry(1)*/ LanRecord.data[0] = (bAuth & authmask); /*Callback level*/ LanRecord.data[1] = (bAuth & authmask); /*User level */ LanRecord.data[2] = (bAuth & authmask); /*Operator level*/ LanRecord.data[3] = (bAuth & authmask); /*Admin level */ LanRecord.data[4] = 0; /*OEM level*/ if (fdebug) printf("SetLanEntry(2): %02x %02x %02x %02x %02x\n", LanRecord.data[0],LanRecord.data[1],LanRecord.data[2], LanRecord.data[3],LanRecord.data[4]); ret = SetLanEntry(2, &LanRecord, 5); printf("SetLanEntry(2), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; /* Get the values to use from Linux eth0, etc. */ ret = Get_IPMac_Addr(); if (lan_dhcp) { /* use DHCP */ LanRecord.data[0] = SRC_DHCP; /* BMC running DHCP */ /* = SRC_BIOS; * address source = BIOS using DHCP */ ret = SetLanEntry(4, &LanRecord, 1); printf("SetLanEntry(4), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; if (MacIsValid(rgmymac)) { memcpy(&LanRecord,rgmymac,6); ret = SetLanEntry(5, &LanRecord, 6); if (ret == 0x82) { /*BMC may not allow the MAC to be set*/ if (fdebug) printf("SetLanEntry(5), ret = %x cannot modify MAC\n",ret); } else { printf("SetLanEntry(5), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } } /* DHCP also relates to OEM LAN params 192, 193, 194 */ if ((vend_id == VENDOR_INTEL) && !fmBMC && !fiBMC) { /*DHCP params 192-194 are Intel only*/ if (IpIsValid(rgmyip)) { /* Set DHCP Server IP in param 192 from -I param. */ memcpy(&LanRecord,rgmyip,4); ret = SetLanEntry(192, &LanRecord, 4); printf("SetLanEntry(192), ret = %d\n",ret); if (!MacIsValid(rgdhcpmac)) /* if MAC not set yet */ ret = Get_Mac(rgmyip,rgdhcpmac,NULL); if (ret == 0) { memcpy(&LanRecord,rgdhcpmac,MAC_LEN); ret = SetLanEntry(193, &LanRecord, MAC_LEN); printf("SetLanEntry(193), ret = %d\n",ret); } } LanRecord.data[0] = 0x01; /*enable DHCP*/ ret = SetLanEntry(194, &LanRecord, 1); printf("SetLanEntry(194), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } } else { /* use static IP */ printf("LAN%d (%s)\tip=%d.%d.%d.%d mac=%02x:%02x:%02x:%02x:%02x:%02x\n", lan_ch,ifname, rgmyip[0], rgmyip[1], rgmyip[2], rgmyip[3], rgmymac[0], rgmymac[1], rgmymac[2], rgmymac[3], rgmymac[4], rgmymac[5]); if (IpIsValid(rgmyip)) { if (lan_ch != gcm_ch) { /*skip if gcm*/ LanRecord.data[0] = 0x00; /*disable grat arp while setting IP*/ ret = SetLanEntry(10, &LanRecord, 1); if (fdebug) printf("SetLanEntry(10,0), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } } LanRecord.data[0] = 0x01; /* static IP address source */ ret = SetLanEntry(4, &LanRecord, 1); printf("SetLanEntry(4), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; memcpy(&LanRecord,rgmyip,4); ret = SetLanEntry(3, &LanRecord, 4); printf("SetLanEntry(3), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; if (MacIsValid(rgmymac)) { memcpy(&LanRecord,rgmymac,6); ret = SetLanEntry(5, &LanRecord, 6); if (ret == 0x82) { /* Do not show anything, not an error if BMC does not allow the BMC MAC to be changed. */ if (fdebug) printf("SetLanEntry(5), ret = %x cannot modify MAC\n",ret); } else { printf("SetLanEntry(5), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } } if (!SubnetIsValid(rgsubnet)) /* not specified, use previous */ memcpy(rgsubnet,bmcsubnet,4); memcpy(&LanRecord,rgsubnet,4); ret = SetLanEntry(6, &LanRecord, 4); printf("SetLanEntry(6), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; if (vend_id != VENDOR_PEPPERCON) { /* may want to check bparm7 here */ LanRecord.data[0] = parm7[0]; /*IPv4 header, TTL */ LanRecord.data[1] = parm7[1]; /*IPv4 header, Flags */ LanRecord.data[2] = parm7[2]; /*IPv4 hdr, Precedence/Service */ ret = SetLanEntry(7, &LanRecord, 3); printf("SetLanEntry(7), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } /* if lan_ch == 3, gcm gets error setting grat arp (ccode=0xCD) */ if (lan_ch != gcm_ch) { /*skip if gcm*/ /* 01=enable grat arp, 02=enable arp resp, 03=both */ LanRecord.data[0] = arp_ctl; /*grat arp*/ ret = SetLanEntry(10, &LanRecord, 1); printf("SetLanEntry(10,%x), ret = %d\n",arp_ctl,ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } LanRecord.data[0] = arp_interval; /*grat arp interval*/ ret = SetLanEntry(11, &LanRecord, 1); printf("SetLanEntry(11), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } if ((vend_id == VENDOR_INTEL) && !fmBMC && !fiBMC) { LanRecord.data[0] = 0x00; /*disable DHCP*/ ret = SetLanEntry(194, &LanRecord, 1); printf("SetLanEntry(194), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } } else { /* error, don't continue */ printf("Missing IP Address, can't continue. Use -I to specify\n"); ret = ERR_BAD_PARAM; goto do_exit; } if (vend_id == VENDOR_KONTRON && rghostname[0] != 0) { /* set the IPMI Hostname if specified */ sz = strlen_(rghostname); /* LanRecord is larger than rghostname, bounds ok */ strncpy((char *)&LanRecord.data,rghostname,sz); ret = SetLanEntry(194, &LanRecord, sz); printf("SetLanEntry(194), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else { LanRecord.data[0] = 0x31; ret = SetLanEntry(195, &LanRecord, 1); /*re-read hostname*/ // printf("SetLanEntry(195), ret = %d\n",ret); // if (ret != 0) { nerrs++; lasterr = ret; } } } if (IpIsValid(rggwyip)) { if (!MacIsValid(rggwymac)) /* if gwy MAC not set by user */ ret = Get_Mac(rggwyip,rggwymac,NULL); printf("gateway \tip=%d.%d.%d.%d mac=%02x:%02x:%02x:%02x:%02x:%02x\n", rggwyip[0], rggwyip[1], rggwyip[2], rggwyip[3], rggwymac[0], rggwymac[1], rggwymac[2], rggwymac[3], rggwymac[4], rggwymac[5]); if (!SubnetIsSame(rgmyip,rggwyip,rgsubnet)) printf("WARNING: IP Address and Gateway are not on the same subnet.\n"); /* Set the Default Gateway IP & MAC */ memcpy(&LanRecord,rggwyip,4); ret = SetLanEntry(12, &LanRecord, 4); printf("SetLanEntry(12), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; if (!MacIsValid(rggwymac)) { /* if gwy MAC not resolved */ printf(" Warning: Gateway MAC address was not resolved! " "Check %s interface, use -i ethN, or use -H gwymac.\n", ifname); } else { memcpy(&LanRecord,rggwymac,6); ret = SetLanEntry(13, &LanRecord, 6); printf("SetLanEntry(13), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } } if (IpIsValid(rggwy2ip)) { if (!MacIsValid(rggwy2mac)) /* if gwy2 MAC not set by user */ ret = Get_Mac(rggwy2ip,rggwy2mac,NULL); /* Set the Secondary Gateway IP & MAC */ memcpy(&LanRecord,rggwy2ip,4); ret = SetLanEntry(14, &LanRecord, 4); printf("SetLanEntry(14), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; memcpy(&LanRecord,rggwy2mac,6); ret = SetLanEntry(15, &LanRecord, 6); printf("SetLanEntry(15), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } } /* end-else static IP */ if (flansecure) { /* disable cipher 0 */ char c1, c2; memset(&LanRecord,0,12); j = 1; for (i = 0; i < nciphers; i+=2) { c1 = rgciphers[i]; c2 = rgciphers[i+1]; /* 0x0f may be vendor-specific, 0x00 = Reserved/Unused */ if (i == ncipher0) c1 = 0x00; if ((i+1) == ncipher0) c2 = 0x00; LanRecord.data[j++] = (c2 << 4) | c1; } ret = SetLanEntry(24, &LanRecord, 9); printf("SetLanEntry(24) disable cipher0, ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } ret = SetupSerialOverLan(1); /*enable*/ SELprintf("SetupSerialOverLan: ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; if (!IpIsValid(rgdestip) && IpIsValid(bmcdestip)) { memcpy(rgdestip,bmcdestip,4); if (fdebug) printf("Using current dest IP %d.%d.%d.%d\n", bmcdestip[0], bmcdestip[1], bmcdestip[2], bmcdestip[3]); } if (ndest == 0) { if (fdebug) printf("ndest==0, anum=%d rgdestip=%d.%d.%d.%d\n", alertnum, rgdestip[0], rgdestip[1], rgdestip[2], rgdestip[3]); printf("alert dest \tnot supported\n"); } else if (!IpIsValid(rgdestip)) { printf("alert dest \taddress not specified\n"); } else { /* valid alert dest ip */ if (!MacIsValid(rgdestmac)) /* if dest MAC not set by user */ ret = Get_Mac(rgdestip,rgdestmac,NULL); /*try to resolve MAC */ if (!MacIsValid(rgdestmac)) { /* if dest MAC not resolved */ printf(" Warning: Alert mac address was not resolved!" " Check %s interface or use -i.\n",ifname); /* use existing BMC alert dest mac (as best guess) */ memcpy(rgdestmac,bmcdestmac,6); } /* show destination data */ printf("alert dest %d\tip=%d.%d.%d.%d mac=%02x:%02x:%02x:%02x:%02x:%02x\n", alertnum, rgdestip[0], rgdestip[1], rgdestip[2], rgdestip[3], rgdestmac[0], rgdestmac[1], rgdestmac[2], rgdestmac[3], rgdestmac[4], rgdestmac[5]); printf("snmp community \t%s\n",rgcommunity); /* Only need the SNMP community if there is an Alert Destination */ memset(&LanRecord.data[0], 0, 18); /* make sure zero-filled */ strcpy(&LanRecord.data[0],rgcommunity); ret = SetLanEntry(16, &LanRecord, 18); printf("SetLanEntry(16), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; /* Set Alert Destination Type */ LanRecord.data[0] = alertnum; /* dest id = 1 */ LanRecord.data[1] = 0x00; /* dest type = PET, no ack */ LanRecord.data[2] = 0x01; /* ack timeout / retry interval */ LanRecord.data[3] = 0x00; /* no retries */ // LanRecord.data[4] = 0x69; ret = SetLanEntry(18, &LanRecord, 4); printf("SetLanEntry(18), ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; { /* Set the Alert Destination IP & MAC (param 19) */ LanRecord.data[0] = alertnum; /* dest id = 1 */ LanRecord.data[1] = 0x00; LanRecord.data[2] = 0x00; memcpy(&LanRecord.data[3],rgdestip,4); memcpy(&LanRecord.data[7],rgdestmac,6); ret = SetLanEntry(19, &LanRecord, 13); printf("SetLanEntry(19), ret = %d\n", ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } } /*endif valid alert*/ /* Now enable PEF since we have an Alert destination. */ if (!fdisable && !fIPMI10 && fpefenable) { /*fpefenable*/ ret = EnablePef(alertnum); printf("EnablePef, ret = %d\n",ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; /* ChanAcc changed, so show it again */ j = ShowChanAcc(lan_ch); } if ((vlan_enable != PARM_INIT) && (fIPMI20)) { if (vlan_enable == 0) { /*disable vlan*/ LanRecord.data[0] = 0x00; LanRecord.data[1] = 0x00; ret = SetLanEntry(20, &LanRecord, 2); printf("SetLanEntry(20,disable) ret = %d\n", ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } else { /*vlan_enable == 1, enable vlan with id */ LanRecord.data[0] = (vlan_id & 0x00ff); LanRecord.data[1] = ((vlan_id & 0x0f00) >> 8) | 0x80; ret = SetLanEntry(20, &LanRecord, 2); printf("SetLanEntry(20,%d), ret = %d\n", vlan_id,ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; LanRecord.data[0] = vlan_prio; ret = SetLanEntry(21, &LanRecord, 1); printf("SetLanEntry(21), ret = %d\n", ret); if (ret != 0) { nerrs++; lasterr = ret; } else ngood++; } } if (failover_enable != PARM_INIT) { if (fRomley) { if (failover_enable > 1) failover_enable = 0; /*default*/ ret = lan_failover_intel(failover_enable,(uchar *)&i); printf("Set Intel Lan Failover (%d), ret = %d\n", failover_enable,ret); if (ret != 0) { nerrs++; lasterr = ret; } } else if (vend_id == VENDOR_SUPERMICROX || vend_id == VENDOR_SUPERMICRO) { if (failover_enable > 2) failover_enable = 2; /*default*/ ret = oem_supermicro_set_lan_port(failover_enable); printf("Set SuperMicro Lan port to %s, ret = %d\n", oem_supermicro_lan_port_string(failover_enable),ret); if (ret != 0) { nerrs++; lasterr = ret; } } } /*endif failover specified*/ } /*end-else not via ipmi_lan*/ } /*endif not readonly*/ if (flanstats) { /* get BMC LAN Statistics */ #ifdef METACOMMAND j = get_lan_stats(lan_ch); #else uchar idata[2]; uchar rdata[20]; int rlen; uchar cc; idata[0] = lan_ch; idata[1] = 0x00; /*do not clear stats*/ rlen = sizeof(rdata); j = ipmi_cmd(GET_LAN_STATS, idata,2, rdata,&rlen, &cc, fdebug); if (j == 0) { /*show BMC LAN stats*/ ushort *rw; rw = (ushort *)&rdata[0]; printf("IPMI LAN channel %d statistics: \n",lan_ch); printf(" \tReceived IP Packets = %d\n",rw[0]); printf(" \tRecvd IP Header errors = %d\n",rw[1]); printf(" \tRecvd IP Address errors = %d\n",rw[2]); printf(" \tRecvd IP Fragments = %d\n",rw[3]); printf(" \tTransmitted IP Packets = %d\n",rw[4]); printf(" \tReceived UDP Packets = %d\n",rw[5]); printf(" \tReceived Valid RMCP Pkts = %d\n",rw[6]); printf(" \tReceived UDP Proxy Pkts = %d\n",rw[7]); printf(" \tDropped UDP Proxy Pkts = %d\n",rw[8]); } #endif } do_exit: ipmi_close_(); if (foptmsg) { if (fset_ip != 0) printf("WARNING: IP address options were specified, but no -e,-l,-d option.\n"); else printf("WARNING: %d options were specified, but no -e,-l,-d option.\n", nopts); printf("Read-only usage assumed.\n"); } if (nerrs > 0) { printf("Warning: %d ok, %d errors occurred, last error = %d\n",ngood,nerrs,lasterr); ret = lasterr; } // show_outcome(progname,ret); return(ret); } /* end main()*/ /* end ilan.c */