/* initialize controller */ inline void padInitialize (padBtnData *pdata ) { dbgprintf ( "pad initializing..." ) ; /* initialize state variables */ pdata->now = 0 ; pdata->last = 0 ; /* initialize semaphore attributes */ pdata->sem_attr.key = PAD_KEY ; pdata->sem_attr.attr_protocol = SYS_SEM_ATTR_PROTOCOL ; pdata->sem_attr.attr_pshared = SYS_SEM_ATTR_PSHARED ; /* initialize mutex attributes */ pdata->mutex_attr.key = PAD_KEY ; pdata->mutex_attr.attr_protocol = SYS_MUTEX_PROTOCOL_FIFO ; pdata->mutex_attr.attr_pshared = SYS_MUTEX_ATTR_PSHARED ; pdata->mutex_attr.attr_recursive = SYS_MUTEX_ATTR_RECURSIVE ; pdata->mutex_attr.attr_adaptive = SYS_MUTEX_ATTR_ADAPTIVE ; /* initialize condition attributes */ pdata->cond_attr.key = PAD_KEY ; pdata->cond_attr.attr_pshared = SYS_COND_ATTR_PSHARED ; /* create semaphore */ //sysSemCreate ( &pdata->sem, &pdata->sem_attr, 1, SEM_CONSUMERS ) ; /* create mutex */ sysMutexCreate ( &pdata->mutex, &pdata->mutex_attr ) ; /* create cond */ sysCondCreate ( &pdata->cond, pdata->mutex, &pdata->cond_attr ) ; ioPadInit ( 7 ) ; }
/* Add a new outchannel line * returns pointer to new object if it succeeds, NULL otherwise. * An outchannel line is primarily a set of fields delemited by commas. * There might be some whitespace between the field (but not within) * and the commas. This can be removed. */ struct outchannel *ochAddLine(char* pName, uchar** ppRestOfConfLine) { struct outchannel *pOch; uchar *p; assert(pName != NULL); assert(ppRestOfConfLine != NULL); if((pOch = ochConstruct()) == NULL) return NULL; pOch->iLenName = strlen(pName); pOch->pszName = (char*) MALLOC(sizeof(char) * (pOch->iLenName + 1)); if(pOch->pszName == NULL) { dbgprintf("ochAddLine could not alloc memory for outchannel name!"); pOch->iLenName = 0; return NULL; /* I know - we create a memory leak here - but I deem * it acceptable as it is a) a very small leak b) very * unlikely to happen. rgerhards 2004-11-17 */ } memcpy(pOch->pszName, pName, pOch->iLenName + 1); /* now actually parse the line */ p = *ppRestOfConfLine; assert(p != NULL); /* get params */ get_Field(&p, &pOch->pszFileTemplate); if(*p) get_off_t(&p, &pOch->uSizeLimit); if(*p) get_restOfLine(&p, &pOch->cmdOnSizeLimit); *ppRestOfConfLine = p; return(pOch); }
static gboolean matecomponent_plug_expose_event (GtkWidget *widget, GdkEventExpose *event) { gboolean retval; retval = GTK_WIDGET_CLASS (matecomponent_plug_parent_class)->expose_event (widget, event); dbgprintf ("matecomponent_plug_expose_event %p (%d, %d), (%d, %d)" "%s (%d && %d == %d)\n", widget, event->area.x, event->area.y, event->area.width, event->area.height, GTK_WIDGET_TOPLEVEL (widget) ? "toplevel" : "bin class", GTK_WIDGET_VISIBLE (widget), GTK_WIDGET_MAPPED (widget), GTK_WIDGET_DRAWABLE (widget)); #ifdef DEBUG_CONTROL gdk_draw_line (widget->window, widget->style->black_gc, event->area.x + event->area.width, event->area.y, event->area.x, event->area.y + event->area.height); gdk_draw_line (widget->window, widget->style->black_gc, widget->allocation.x, widget->allocation.y, widget->allocation.x + widget->allocation.width, widget->allocation.y + widget->allocation.height); #endif return retval; }
static void ChargeConsume(int pktlen) { struct timeval now; if (g_ctc_packets) g_ctc_packets--; if (g_ctc_bytes) g_ctc_bytes -= pktlen; IF_TRACED(TRC_CHARGE) dbgprintf("ChargeConsume: CTC now has bytes=" FMT_UINT32 " & packets=" FMT_UINT32 "\n", g_ctc_bytes, g_ctc_packets); END_TRACE /* Reset charge timer */ gettimeofday(&now, NULL); timeval_add_ms(&now, TOPO_CHARGE_TIMEOUT); CANCEL(g_charge_timer); g_charge_timer = event_add(&now, state_charge_timeout, /*state:*/NULL); }
static void matecomponent_control_destroy (MateComponentObject *object) { MateComponentControl *control = (MateComponentControl *) object; dbgprintf ("matecomponent_control_destroy %p\n", object); if (control->priv->plug) matecomponent_control_set_plug (control, NULL); matecomponent_control_unset_control_frame (control, NULL); matecomponent_control_set_properties (control, CORBA_OBJECT_NIL, NULL); matecomponent_control_set_ui_component (control, NULL); matecomponent_control_disconnected (control); if (control->priv->widget) { gtk_widget_destroy (GTK_WIDGET (control->priv->widget)); g_object_unref (control->priv->widget); } control->priv->widget = NULL; control->priv->popup_ui_container = matecomponent_object_unref ( (MateComponentObject *) control->priv->popup_ui_container); if (control->priv->popup_ui_engine) g_object_unref (control->priv->popup_ui_engine); control->priv->popup_ui_engine = NULL; control->priv->popup_ui_component = matecomponent_object_unref ( (MateComponentObject *) control->priv->popup_ui_component); control->priv->popup_ui_sync = NULL; control->priv->inproc_frame = NULL; MATECOMPONENT_OBJECT_CLASS (matecomponent_control_parent_class)->destroy (object); }
char *csp_header(const char *str) { char *csppol = NULL; char *returnstr = NULL; if (getenv("XYMON_NOCSPHEADER")) return NULL; if (strncmp(str, "enadis", 6) == 0) csppol = strdup("script-src 'self' 'unsafe-inline'; connect-src 'self'; form-action 'self'; sandbox allow-forms allow-scripts;"); else if (strncmp(str, "useradm", 7) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "chpasswd", 8) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "ackinfo", 7) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "acknowledge", 11) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "criticaleditor", 14) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "svcstatus", 9) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self'; sandbox allow-forms;"); else if (strncmp(str, "historylog", 10) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self'; sandbox allow-forms;"); else { errprintf(" csp_header: page %s not listed, no CSP returned\n", str); } if ((!csppol) || (*csppol == '\0')) return NULL; returnstr = (char *)malloc(3 * strlen(csppol) + 512); snprintf(returnstr, (3 * strlen(csppol) + 512), "Content-Security-Policy: %s\nX-Content-Security-Policy: %s\nX-Webkit-CSP: %s\n", csppol, csppol, csppol); dbgprintf("CSP return is %s", returnstr); return returnstr; }
void update_enable(char *fn, time_t expiretime) { time_t now = getcurrenttime(NULL); dbgprintf("Enable/disable file %s, time %d\n", fn, (int)expiretime); if (expiretime <= now) { if (unlink(fn) != 0) { errprintf("Could not remove disable-file '%s':%s\n", fn, strerror(errno)); } } else { FILE *enablefd; struct utimbuf logtime; enablefd = fopen(fn, "w"); if (enablefd) { fclose(enablefd); } logtime.actime = logtime.modtime = expiretime; utime(fn, &logtime); } }
void matecomponent_control_add_listener (CORBA_Object object, GCallback fn, gpointer user_data, CORBA_Environment *ev) { MateCORBAConnectionStatus status; if (object == CORBA_OBJECT_NIL) return; status = MateCORBA_small_listen_for_broken ( object, fn, user_data); switch (status) { case MATECORBA_CONNECTION_CONNECTED: break; default: dbgprintf ("premature CORBA_Object death"); matecomponent_exception_general_error_set ( ev, NULL, "Control died prematurely"); break; } }
bool PatchWidescreen(u32 FirstVal, u32 Buffer) { if(FirstVal == FLT_ASPECT_0_913 && read32(Buffer+4) == 0x2e736200) { write32(Buffer, FLT_ASPECT_1_218); dbgprintf("PatchWidescreen:[Aspect Ratio 1.218] applied (0x%08X)\r\n", Buffer ); return true; } else if(FirstVal == FLT_ASPECT_1_200 && (read32(Buffer+4) == 0x43F00000 || (read32(Buffer+4) == 0 && read32(Buffer+8) == 0x43F00000))) { //All Mario Party games share this value write32(Buffer, FLT_ASPECT_1_600); dbgprintf("PatchWidescreen:[Aspect Ratio 1.600] applied (0x%08X)\r\n", Buffer ); return true; } else if(FirstVal == FLT_ASPECT_1_266 && read32(Buffer+4) == 0x44180000) { write32(Buffer, FLT_ASPECT_1_688); dbgprintf("PatchWidescreen:[Aspect Ratio 1.688] applied (0x%08X)\r\n", Buffer ); return true; } else if(FirstVal == FLT_ASPECT_1_333 && (read32(Buffer+4) == 0x481c4000 || read32(Buffer+4) == 0x3f800000 || read32(Buffer+4) == 0xbf800000)) { write32(Buffer, FLT_ASPECT_1_777); dbgprintf("PatchWidescreen:[Aspect Ratio 1.777] applied (0x%08X)\r\n", Buffer ); return true; } else if(FirstVal == FLT_ASPECT_1_357 && read32(Buffer+4) == 0x481c4000) { write32(Buffer, FLT_ASPECT_1_809); dbgprintf("PatchWidescreen:[Aspect Ratio 1.809] applied (0x%08X)\r\n", Buffer ); return true; } else if(FirstVal == FLT_ASPECT_1_428 && read32(Buffer+4) == 0x3e99999a) { write32(Buffer, FLT_ASPECT_1_905); dbgprintf("PatchWidescreen:[Aspect Ratio 1.905] applied (0x%08X)\r\n", Buffer ); return true; } return false; }
int _start(int argc,char** argv) { sys_sem_t Sema; int iRet; dbgprintf("PS2IP: Module Loaded.\n"); if ((iRet=RegisterLibraryEntries(&_exp_ps2ip))!=0) { printf("PS2IP: RegisterLibraryEntries returned: %d\n",iRet); } sys_init(); mem_init(); memp_init(); pbuf_init(); dbgprintf("PS2IP: sys_init, mem_init, memp_init, pbuf_init called\n"); netif_init(); dbgprintf("PS2IP: netif_init called\n"); Sema=sys_sem_new(0); dbgprintf("PS2IP: Calling tcpip_init\n"); tcpip_init(InitDone,&Sema); sys_arch_sem_wait(Sema,0); sys_sem_free(Sema); dbgprintf("PS2IP: tcpip_init called\n"); AddLoopIF(); InitTimer(); dbgprintf("PS2IP: System Initialised\n"); return iRet; }
static GSM_Error loadnsl(FILE *file, GSM_MultiBitmap *bitmap) { unsigned char block[6],buffer[505]; size_t block_size; size_t readbytes; GSM_Bitmap_Types OldType; while (fread(block,1,6,file)==6) { block_size = block[4]*256 + block[5]; dbgprintf(NULL, "Block %c%c%c%c, size %ld\n",block[0],block[1],block[2],block[3],(long)block_size); if (!strncmp(block, "FORM", 4)) { dbgprintf(NULL, "File ID\n"); } else { if (block_size>504) return ERR_FILENOTSUPPORTED; if (block_size!=0) { readbytes = fread(buffer,1,block_size,file); if (readbytes != block_size) return ERR_FILENOTSUPPORTED; /* if it's string, we end it with 0 */ buffer[block_size]=0; #ifdef DEBUG if (!strncmp(block, "VERS", 4)) dbgprintf(NULL, "File saved by: %s\n",buffer); if (!strncmp(block, "MODL", 4)) dbgprintf(NULL, "Logo saved from: %s\n",buffer); if (!strncmp(block, "COMM", 4)) dbgprintf(NULL, "Phone was connected to COM port: %s\n",buffer); #endif if (!strncmp(block, "NSLD", 4)) { bitmap->Bitmap[0].BitmapHeight = 48; bitmap->Bitmap[0].BitmapWidth = 84; OldType = bitmap->Bitmap[0].Type; PHONE_DecodeBitmap(GSM_NokiaStartupLogo, buffer, &bitmap->Bitmap[0]); if (OldType != GSM_None) bitmap->Bitmap[0].Type = OldType; dbgprintf(NULL, "Startup logo (size %ld)\n",(long)block_size); } } } } bitmap->Number = 1; return(ERR_NONE); }
/* check controller buttons */ inline int padCheckState ( padBtnData *pdata ) { s32 ret = padCheck ( pdata ) ; switch ( ret ) { case 0: break ; case PAD_TRIANGLE: dbgprintf ( "PAD_TRIANGLE" ) ; *pdata->exitapp = 1 ; break ; case PAD_CIRCLE: dbgprintf ( "PAD_CIRCLE" ) ; *pdata->exitapp = 1 ; break ; case PAD_CROSS: dbgprintf ( "PAD_CROSS" ) ; *pdata->exitapp = 0 ; break ; case PAD_SQUARE: dbgprintf ( "PAD_SQUARE" ) ; *pdata->exitapp = 1 ; break ; case PAD_SELECT: dbgprintf ( "PAD_SELECT" ) ; *pdata->exitapp = 1 ; break ; case PAD_START: dbgprintf ( "PAD_START" ) ; *pdata->exitapp = 0 ; break ; default: argprintf ( "default: %d", ret ) ; break ; } return 0 ; }
static void event_read_siblings(char* directory) { static unsigned read_limit; static int has_read_limit = 0; char discard[4096], subfile[4096]; unsigned data_read, amt; DIR* dir; FILE* file; struct dirent* ent; struct stat st; int is_regular; dbgprintf(stderr, "daemon: siblings %s\n", directory); if (!has_read_limit) { has_read_limit = 1; read_limit = 16; if (getenv("CHISTKA_SIBLINGS")) read_limit = atoi(getenv("CHISTKA_SIBLINGS")); read_limit *= 1024*1024; } dir = opendir(directory); if (!dir) return; data_read = 0; /* Iterate through the directory and read any regular file encountered */ while (data_read < read_limit && (ent = readdir(dir))) { read_input(); if (sizeof(subfile) > strlen(directory) + 1 /* slash */ + strlen(ent->d_name)) { strcpy(subfile, directory); strcat(subfile, "/"); strcat(subfile, ent->d_name); } else { /* Path name too long */ continue; } /* If possible, get the type of the file from the dirent. If we get * unknown, or the system does not have DT_REG and DT_UNKNOWN, resort to * stat()ing the file to find out what it is. */ #if defined(DT_REG) && defined(DT_UNKNOWN) if (ent->d_type == DT_REG) { is_regular = 1; } else if (ent->d_type == DT_UNKNOWN) { #endif /* Either the filesystem can't tell us what the file is, or the system * doesn't support returning file types within the dirent. * * Stat the file to find out what it is. */ is_regular = !stat(subfile, &st) && S_ISREG(st.st_mode); #if defined(DT_REG) && defined(DT_UNKNOWN) } else { /* Known and not REG */ is_regular = 0; } #endif if (is_regular && (file = fopen(subfile, "r"))) { dbgprintf(stderr, "daemon: sibling read: %s\n", subfile); do { read_input(); amt = fread(discard, 1, sizeof(discard), file); data_read += amt; } while (amt == sizeof(discard) && data_read < read_limit); fclose(file); } } closedir(dir); }
/* Dummy event for testing */ static void event_print(char* filename) { dbgprintf(stderr, "daemon: %s\n", filename); }
/* allows a user to run as us */ int main(int argc, char **argv) { int ok, arg, status; FILE *infd; struct utsname udata; struct stat statbuf; struct passwd *pw; char *pc, inbuf[BUFSIZ]; char user[BUFSIZ], mach[BUFSIZ], cmd[BUFSIZ]; char alwduser[BUFSIZ], alwdmach[BUFSIZ], alwdcmd[BUFSIZ]; /* open debug file */ dbgopen(DEBUGFILE); /* check if any cmds were given */ DBGDUMP("%s\n", "starting suid ..."); if (argc < 2) { dbgprintf("%s: no cmds given. (errno=%d)\n", argv[0], EINVAL); fprintf(stderr, "%s: no cmds given. (errno=%d)\n", argv[0], EINVAL); dbgclose(); exit(2); } /* dump ids */ DBGDUMP("uid = %d\n", getuid()); DBGDUMP("euid = %d\n", geteuid()); DBGDUMP("gid = %d\n", getgid()); DBGDUMP("egid = %d\n", getegid()); /* this tool is used specifically to allow set-uid. * if the setuid has not taken, then we should error * out immediately. verify that the effective uid * matches the owning uid for the suid tool. */ DBGDUMP("%s\n", "checking SETUID worked ..."); if (stat(SUID_PATH, &statbuf) != 0) { dbgprintf("%s: stat failed for file %s. (errno=%d)\n", argv[0], SUID_PATH, errno); fprintf(stderr, "%s: stat failed for file %s. (errno=%d)\n", argv[0], SUID_PATH, errno); exit(2); } if (statbuf.st_uid != geteuid()) { dbgprintf("%s: SUID != EUID !!!. SUID=%d, EUID=%d\n", argv[0], statbuf.st_uid, geteuid()); fprintf(stderr, "%s: SET UID FAILED !!!. EUID=%d, SUID=%d\n", argv[0], statbuf.st_uid, geteuid()); dbgclose(); exit(2); } if (statbuf.st_gid != getegid()) { dbgprintf("%s: SGID != EGID !!!. SGID=%d, EGID=%d\n", argv[0], statbuf.st_gid, getegid()); fprintf(stderr, "%s: SET GID FAILED !!!. EGID=%d, SGID=%d\n", argv[0], statbuf.st_gid, getegid()); dbgclose(); exit(2); } /* set environment variable to indicate owner called a tool */ DBGDUMP("statbuf.st_uid = %d\n", statbuf.st_uid); DBGDUMP("statbuf.st_gid = %d\n", statbuf.st_gid); DBGDUMP("getuid = %d\n", getuid()); DBGDUMP("getgid = %d\n", getgid()); if ((statbuf.st_uid == getuid()) && (statbuf.st_gid == getgid())) { DBGDUMP("FILEOWNER ... %s\n", owneryes); (void)putenv(owneryes); } else { DBGDUMP("FILEOWNER ... %s\n", ownerno); (void)putenv(ownerno); } /* get the name of the current machine */ DBGDUMP("%s\n", "calling uname ..."); if (uname(&udata) == -1) { dbgprintf("%s: uname failed. (errno=%d)\n", argv[0], errno); fprintf(stderr, "%s: uname failed. (errno=%d)\n", argv[0], errno); dbgclose(); exit(2); } strcpy(mach, udata.nodename); DBGDUMP("machine is %s\n", mach); /* get name of current user; user REAL UID, not EFFECTIVE UID */ DBGDUMP("calling getpwuid with uid=%d\n", getuid()); if ((pw = getpwuid(getuid())) == NULL) { dbgprintf("%s: unable to determine user name. (errno=%d)\n", argv[0], errno); fprintf(stderr, "%s: unable to determine user name. (errno=%d)\n", argv[0], errno); dbgclose(); exit(2); } strcpy(user, pw->pw_name); DBGDUMP("user is %s\n", user); /* open file of allowed commands */ DBGDUMP("opening file %s for read\n", ALLOWED_CMDS); if ((infd = fopen(ALLOWED_CMDS, "r")) == NULL) { dbgprintf("%s: allows cmds file %s not readable. (errno=%d)\n", argv[0], ALLOWED_CMDS, errno); fprintf(stderr, "%s: allows cmds file %s not readable. (errno=%d)\n", argv[0], ALLOWED_CMDS, errno); dbgclose(); exit(2); } DBGDUMP("allowed cmds file is %s\n", ALLOWED_CMDS); /* scan if cmd is allowed on this machine for this user */ ok = 0; strcpy(cmd, argv[1]); while (fgets(inbuf, BUFSIZ-1, infd) != NULL) { stripnl(inbuf); if (*inbuf == '#' || *inbuf == '\0') continue; sscanf(inbuf, "%s%s%s", alwdmach, alwduser, alwdcmd); if (strcmp(cmd, alwdcmd) == 0 && (strcmp(alwduser, "*") == 0 || strcmp(user, alwduser) == 0) && (strcmp(alwdmach, "*") == 0 || strcmp(mach, alwdmach) == 0)) { ok = 1; break; } } if (!ok) { dbgprintf("%s: cmd %s not allowed on machine %s for user %s.\n", argv[0], cmd, mach, user); fprintf(stderr, "%s: cmd %s not allowed on machine %s for user %s.\n", argv[0], cmd, mach, user); dbgclose(); exit(2); } DBGDUMP("cmd %s is allowed\n", cmd); /* make sure euid is set */ setuid(geteuid()); setgid(getegid()); /* put together one big command */ cmd[0] = '\0'; for (pc = cmd, arg = 1; arg < argc; arg++, pc++) { strcpy(pc, argv[arg]); pc += strlen(argv[arg]); *pc = ' '; } *pc = '\0'; /* run the command */ DBGDUMP("excuting cmd %s ...\n", cmd); status = system(cmd); DBGDUMP("return value is %d ...\n", status); status >>= 8; DBGDUMP("return value after shift is %d ...\n", status); /* close debug file */ dbgclose(); /* return status */ exit(status); }
void readconfig(char *cfgfn, int verbose) { static void *cfgfiles = NULL; FILE *cfgfd; strbuffer_t *inbuf; struct req_t *reqitem = NULL; int tasksleep = atoi(xgetenv("TASKSLEEP")); mibdef_t *mib; /* Check if config was modified */ if (cfgfiles) { if (!stackfmodified(cfgfiles)) { dbgprintf("No files changed, skipping reload\n"); return; } else { stackfclist(&cfgfiles); cfgfiles = NULL; } } cfgfd = stackfopen(cfgfn, "r", &cfgfiles); if (cfgfd == NULL) { errprintf("Cannot open configuration files %s\n", cfgfn); return; } inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { char *bot, *p, *mibidx; char savech; sanitize_input(inbuf, 0, 0); bot = STRBUF(inbuf) + strspn(STRBUF(inbuf), " \t"); if ((*bot == '\0') || (*bot == '#')) continue; if (*bot == '[') { char *intvl = strchr(bot, '/'); /* * See if we're running a non-standard interval. * If yes, then process only the records that match * this TASKSLEEP setting. */ if (tasksleep != 300) { /* Non-default interval. Skip the host if it HASN'T got an interval setting */ if (!intvl) continue; /* Also skip the hosts that have an interval different from the current */ *intvl = '\0'; /* Clip the interval from the hostname */ if (atoi(intvl+1) != tasksleep) continue; } else { /* Default interval. Skip the host if it HAS an interval setting */ if (intvl) continue; } reqitem = (req_t *)calloc(1, sizeof(req_t)); p = strchr(bot, ']'); if (p) *p = '\0'; reqitem->hostname = strdup(bot + 1); if (p) *p = ']'; reqitem->hostip[0] = reqitem->hostname; reqitem->version = SNMP_VERSION_1; reqitem->authmethod = SNMP_V3AUTH_MD5; reqitem->next = reqhead; reqhead = reqitem; continue; } /* If we have nowhere to put the data, then skip further processing */ if (!reqitem) continue; if (strncmp(bot, "ip=", 3) == 0) { char *nextip = strtok(strdup(bot+3), ","); int i = 0; do { reqitem->hostip[i++] = nextip; nextip = strtok(NULL, ","); } while (nextip); continue; } if (strncmp(bot, "version=", 8) == 0) { switch (*(bot+8)) { case '1': reqitem->version = SNMP_VERSION_1; break; case '2': reqitem->version = SNMP_VERSION_2c; break; case '3': reqitem->version = SNMP_VERSION_3; break; } continue; } if (strncmp(bot, "community=", 10) == 0) { reqitem->community = strdup(bot+10); continue; } if (strncmp(bot, "username="******"passphrase=", 10) == 0) { reqitem->passphrase = strdup(bot+10); continue; } if (strncmp(bot, "authmethod=", 10) == 0) { if (strcasecmp(bot+10, "md5") == 0) reqitem->authmethod = SNMP_V3AUTH_MD5; else if (strcasecmp(bot+10, "sha1") == 0) reqitem->authmethod = SNMP_V3AUTH_SHA1; else errprintf("Unknown SNMPv3 authentication method '%s'\n", bot+10); continue; } /* Custom mibs */ p = bot + strcspn(bot, "= \t\r\n"); savech = *p; *p = '\0'; mib = find_mib(bot); *p = savech; p += strspn(p, "= \t"); mibidx = p; if (mib) { int i; mibidx_t *iwalk = NULL; char *oid, *oidbuf; char *devname; oidset_t *swalk; setupmib(mib, verbose); if (mib->loadstatus != MIB_STATUS_LOADED) continue; /* Cannot use this MIB */ /* See if this is an entry where we must determine the index ourselves */ if (*mibidx) { for (iwalk = mib->idxlist; (iwalk && (*mibidx != iwalk->marker)); iwalk = iwalk->next) ; } if ((*mibidx == '*') && !iwalk) { errprintf("Cannot do wildcard matching without an index (host %s, mib %s)\n", reqitem->hostname, mib->mibname); continue; } if (!iwalk) { /* No key lookup */ swalk = mib->oidlisthead; while (swalk) { reqitem->setnumber++; for (i=0; (i <= swalk->oidcount); i++) { if (*mibidx) { oid = oidbuf = (char *)malloc(strlen(swalk->oids[i].oid) + strlen(mibidx) + 2); sprintf(oidbuf, "%s.%s", swalk->oids[i].oid, mibidx); devname = mibidx; } else { oid = swalk->oids[i].oid; oidbuf = NULL; devname = "-"; } make_oitem(mib, devname, &swalk->oids[i], oid, reqitem); if (oidbuf) xfree(oidbuf); } swalk = swalk->next; } reqitem->next_oid = reqitem->oidhead; } else { /* Add a key-record so we can try to locate the index */ keyrecord_t *newitem = (keyrecord_t *)calloc(1, sizeof(keyrecord_t)); char endmarks[6]; mibidx++; /* Skip the key-marker */ sprintf(endmarks, "%s%c", ")]}>", iwalk->marker); p = mibidx + strcspn(mibidx, endmarks); *p = '\0'; newitem->key = strdup(mibidx); newitem->indexmethod = iwalk; newitem->mib = mib; newitem->next = reqitem->keyrecords; reqitem->currentkey = reqitem->keyrecords = newitem; } continue; } else { errprintf("Unknown MIB (not in snmpmibs.cfg): '%s'\n", bot); } } stackfclose(cfgfd); freestrbuffer(inbuf); }
/* * response handler */ int asynch_response(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic) { struct req_t *req = (struct req_t *)magic; if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) { struct snmp_pdu *snmpreq = NULL; int okoid = 1; if (dataoperation == GET_KEYS) { /* * We're doing GETNEXT's when retrieving keys, so we will get a response * which has nothing really to do with the data we're looking for. In that * case, we should NOT process data from this response. */ struct variable_list *vp = pdu->variables; okoid = ((vp->name_length >= req->currentkey->indexmethod->rootoidlen) && (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0)); } switch (pdu->errstat) { case SNMP_ERR_NOERROR: /* Pick up the results, but only if the OID is valid */ if (okoid) print_result(STAT_SUCCESS, req, pdu); break; case SNMP_ERR_NOSUCHNAME: dbgprintf("Host %s item %s: No such name\n", req->hostname, req->curr_oid->devname); if (req->hostip[req->hostipidx+1]) { req->hostipidx++; startonehost(req, 1); } break; case SNMP_ERR_TOOBIG: toobigcount++; errprintf("Host %s item %s: Response too big\n", req->hostname, req->curr_oid->devname); break; default: errorcount++; errprintf("Host %s item %s: SNMP error %d\n", req->hostname, req->curr_oid->devname, pdu->errstat); break; } /* Now see if we should send another request */ switch (dataoperation) { case GET_KEYS: /* * While fetching keys, walk the current key-table until we reach the end of the table. * When we reach the end of one key-table, start with the next. * FIXME: Could optimize so we dont fetch the whole table, but only those rows we need. */ if (pdu->errstat == SNMP_ERR_NOERROR) { struct variable_list *vp = pdu->variables; if ( (vp->name_length >= req->currentkey->indexmethod->rootoidlen) && (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0) ) { /* Still more data in the current key table, get the next row */ snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT); pducount++; /* Probably only one variable to fetch, but never mind ... */ while (vp) { varcount++; snmp_add_null_var(snmpreq, vp->name, vp->name_length); vp = vp->next_variable; } } else { /* End of current key table. If more keys to be found, start the next table. */ do { req->currentkey = req->currentkey->next; } while (req->currentkey && req->currentkey->indexoid); if (req->currentkey) { snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT); pducount++; snmp_add_null_var(snmpreq, req->currentkey->indexmethod->rootoid, req->currentkey->indexmethod->rootoidlen); } } } break; case GET_DATA: /* Generate a request for the next dataset, if any */ if (req->next_oid) { snmpreq = generate_datarequest(req); } else { dbgprintf("No more oids left\n"); } break; } /* Send the request we just made */ if (snmpreq) { if (snmp_send(req->sess, snmpreq)) goto finish; else { snmp_sess_perror("snmp_send", req->sess); snmp_free_pdu(snmpreq); } } } else { dbgprintf("operation not succesful: %d\n", operation); print_result(STAT_TIMEOUT, req, pdu); } /* * Something went wrong (or end of variables). * This host not active any more */ dbgprintf("Finished host %s\n", req->hostname); active_requests--; finish: /* Start some more hosts */ starthosts(0); return 1; }
/* * Store data received in response PDU */ int print_result (int status, req_t *req, struct snmp_pdu *pdu) { struct variable_list *vp; size_t len; keyrecord_t *kwalk; int keyoidlen; oid_t *owalk; int done; switch (status) { case STAT_SUCCESS: if (pdu->errstat == SNMP_ERR_NOERROR) { unsigned char *valstr = NULL, *oidstr = NULL; size_t valsz = 0, oidsz = 0; okcount++; switch (dataoperation) { case GET_KEYS: /* * Find the keyrecord currently processed for this request, and * look through the unresolved keys to see if we have a match. * If we do, determine the index for data retrieval. */ vp = pdu->variables; len = 0; sprint_realloc_value(&valstr, &valsz, &len, 1, vp->name, vp->name_length, vp); len = 0; sprint_realloc_objid(&oidstr, &oidsz, &len, 1, vp->name, vp->name_length); dbgprintf("Got key-oid '%s' = '%s'\n", oidstr, valstr); for (kwalk = req->currentkey, done = 0; (kwalk && !done); kwalk = kwalk->next) { /* Skip records where we have the result already, or that are not keyed */ if (kwalk->indexoid || (kwalk->indexmethod != req->currentkey->indexmethod)) { continue; } keyoidlen = strlen(req->currentkey->indexmethod->keyoid); switch (kwalk->indexmethod->idxtype) { case MIB_INDEX_IN_OID: /* Does the key match the value we just got? */ if (*kwalk->key == '*') { /* Match all. Add an extra key-record at the end. */ keyrecord_t *newkey; newkey = (keyrecord_t *)calloc(1, sizeof(keyrecord_t)); memcpy(newkey, kwalk, sizeof(keyrecord_t)); newkey->indexoid = strdup(oidstr + keyoidlen + 1); newkey->key = valstr; valstr = NULL; newkey->next = kwalk->next; kwalk->next = newkey; done = 1; } else if (strcmp(valstr, kwalk->key) == 0) { /* Grab the index part of the OID */ kwalk->indexoid = strdup(oidstr + keyoidlen + 1); done = 1; } break; case MIB_INDEX_IN_VALUE: /* Does the key match the index-part of the result OID? */ if (*kwalk->key == '*') { /* Match all. Add an extra key-record at the end. */ keyrecord_t *newkey; newkey = (keyrecord_t *)calloc(1, sizeof(keyrecord_t)); memcpy(newkey, kwalk, sizeof(keyrecord_t)); newkey->indexoid = valstr; valstr = NULL; newkey->key = strdup(oidstr + keyoidlen + 1); newkey->next = kwalk->next; kwalk->next = newkey; done = 1; } else if ((*(oidstr+keyoidlen) == '.') && (strcmp(oidstr+keyoidlen+1, kwalk->key)) == 0) { /* * Grab the index which is the value. * Avoid a strdup by grabbing the valstr pointer. */ kwalk->indexoid = valstr; valstr = NULL; valsz = 0; done = 1; } break; } } break; case GET_DATA: owalk = req->curr_oid; vp = pdu->variables; while (vp) { valsz = len = 0; sprint_realloc_value((unsigned char **)&owalk->result, &valsz, &len, 1, vp->name, vp->name_length, vp); owalk = owalk->next; vp = vp->next_variable; } break; } if (valstr) xfree(valstr); if (oidstr) xfree(oidstr); } else { errorcount++; errprintf("ERROR %s: %s\n", req->hostip[req->hostipidx], snmp_errstring(pdu->errstat)); } return 1; case STAT_TIMEOUT: timeoutcount++; dbgprintf("%s: Timeout\n", req->hostip); if (req->hostip[req->hostipidx+1]) { req->hostipidx++; startonehost(req, 1); } return 0; case STAT_ERROR: errorcount++; snmp_sess_perror(req->hostip[req->hostipidx], req->sess); return 0; } return 0; }
int main (int argc, char **argv) { SDL_Surface *s = NULL; if (argc == 1){ fprintf(stderr, "pictool: no input files\n"); exit(1); } if(argc == 2){ if(!strcmp(argv[1], "--help")){ show_help(); exit(0); } else{ if(picdetails(argv[1])){ fprintf(stderr, "pictool: bad format\n"); exit(4); } exit(0); } } if(argc == 3){ fprintf(stderr, "pictool: not enough arguments\n"); exit(2); } SDL_Init(SDL_INIT_VIDEO); if(argc == 5 && !strcmp(argv[4], "--topic")){ int error; dbgprintf(":: Loading from bitmap %s\n", argv[3]); s = SDL_LoadBMP(argv[3]); dbgprintf(":: Success\n"); if (error = writepic(argv[1], atoi(argv[2]), s)) { printf("Error writing pic: %d\n", error); exit(error); } SDL_FreeSurface(s); } else if(argc == 4 || !strcmp(argv[4], "--tobmp")){ if(readpic(argv[1], atoi(argv[2]), &s)){ fprintf(stderr, "pictool: conversion to bmp failed: bad format\n"); SDL_Quit(); exit(4); } dbgprintf(":: Saving to %s\n", argv[3]); if(SDL_SaveBMP(s, argv[3])){ fprintf(stderr, "pictool: saving to bmp failed\n"); SDL_Quit(); exit(6); } dbgprintf(":: Success\n"); SDL_FreeSurface(s); } else{ fprintf(stderr, "pictool: unrecognized argument\n"); SDL_Quit(); exit(5); } dbgprintf(":: SDLQuit\n"); SDL_Quit(); dbgprintf(":: Return\n"); return 0; }
/* * getID - Determines the ID of an instruction, consuming the ModR/M byte as * appropriate for extended and escape opcodes. Determines the attributes and * context for the instruction before doing so. * * @param insn - The instruction whose ID is to be determined. * @return - 0 if the ModR/M could be read when needed or was not needed; * nonzero otherwise. */ static int getID(struct InternalInstruction* insn, void *miiArg) { uint8_t attrMask; uint16_t instructionID; dbgprintf(insn, "getID()"); attrMask = ATTR_NONE; if (insn->mode == MODE_64BIT) attrMask |= ATTR_64BIT; if (insn->vexSize) { attrMask |= ATTR_VEX; if (insn->vexSize == 3) { switch (ppFromVEX3of3(insn->vexPrefix[2])) { case VEX_PREFIX_66: attrMask |= ATTR_OPSIZE; break; case VEX_PREFIX_F3: attrMask |= ATTR_XS; break; case VEX_PREFIX_F2: attrMask |= ATTR_XD; break; } if (lFromVEX3of3(insn->vexPrefix[2])) attrMask |= ATTR_VEXL; } else if (insn->vexSize == 2) { switch (ppFromVEX2of2(insn->vexPrefix[1])) { case VEX_PREFIX_66: attrMask |= ATTR_OPSIZE; break; case VEX_PREFIX_F3: attrMask |= ATTR_XS; break; case VEX_PREFIX_F2: attrMask |= ATTR_XD; break; } if (lFromVEX2of2(insn->vexPrefix[1])) attrMask |= ATTR_VEXL; } else { return -1; } } else { if (isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) attrMask |= ATTR_OPSIZE; else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation)) attrMask |= ATTR_ADSIZE; else if (isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation)) attrMask |= ATTR_XS; else if (isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation)) attrMask |= ATTR_XD; } if (insn->rexPrefix & 0x08) attrMask |= ATTR_REXW; if (getIDWithAttrMask(&instructionID, insn, attrMask)) return -1; /* The following clauses compensate for limitations of the tables. */ if ((attrMask & ATTR_VEXL) && (attrMask & ATTR_REXW) && !(attrMask & ATTR_OPSIZE)) { /* * Some VEX instructions ignore the L-bit, but use the W-bit. Normally L-bit * has precedence since there are no L-bit with W-bit entries in the tables. * So if the L-bit isn't significant we should use the W-bit instead. * We only need to do this if the instruction doesn't specify OpSize since * there is a VEX_L_W_OPSIZE table. */ const struct InstructionSpecifier *spec; uint16_t instructionIDWithWBit; const struct InstructionSpecifier *specWithWBit; spec = specifierForUID(instructionID); if (getIDWithAttrMask(&instructionIDWithWBit, insn, (attrMask & (~ATTR_VEXL)) | ATTR_REXW)) { insn->instructionID = instructionID; insn->spec = spec; return 0; } specWithWBit = specifierForUID(instructionIDWithWBit); if (instructionID != instructionIDWithWBit) { insn->instructionID = instructionIDWithWBit; insn->spec = specWithWBit; } else { insn->instructionID = instructionID; insn->spec = spec; } return 0; } if (insn->prefixPresent[0x66] && !(attrMask & ATTR_OPSIZE)) { /* * The instruction tables make no distinction between instructions that * allow OpSize anywhere (i.e., 16-bit operations) and that need it in a * particular spot (i.e., many MMX operations). In general we're * conservative, but in the specific case where OpSize is present but not * in the right place we check if there's a 16-bit operation. */ const struct InstructionSpecifier *spec; uint16_t instructionIDWithOpsize; const char *specName, *specWithOpSizeName; spec = specifierForUID(instructionID); if (getIDWithAttrMask(&instructionIDWithOpsize, insn, attrMask | ATTR_OPSIZE)) { /* * ModRM required with OpSize but not present; give up and return version * without OpSize set */ insn->instructionID = instructionID; insn->spec = spec; return 0; } specName = x86DisassemblerGetInstrName(instructionID, miiArg); specWithOpSizeName = x86DisassemblerGetInstrName(instructionIDWithOpsize, miiArg); if (is16BitEquvalent(specName, specWithOpSizeName)) { insn->instructionID = instructionIDWithOpsize; insn->spec = specifierForUID(instructionIDWithOpsize); } else { insn->instructionID = instructionID; insn->spec = spec; } return 0; } if (insn->opcodeType == ONEBYTE && insn->opcode == 0x90 && insn->rexPrefix & 0x01) { /* * NOOP shouldn't decode as NOOP if REX.b is set. Instead * it should decode as XCHG %r8, %eax. */ const struct InstructionSpecifier *spec; uint16_t instructionIDWithNewOpcode; const struct InstructionSpecifier *specWithNewOpcode; spec = specifierForUID(instructionID); /* Borrow opcode from one of the other XCHGar opcodes */ insn->opcode = 0x91; if (getIDWithAttrMask(&instructionIDWithNewOpcode, insn, attrMask)) { insn->opcode = 0x90; insn->instructionID = instructionID; insn->spec = spec; return 0; } specWithNewOpcode = specifierForUID(instructionIDWithNewOpcode); /* Change back */ insn->opcode = 0x90; insn->instructionID = instructionIDWithNewOpcode; insn->spec = specWithNewOpcode; return 0; } insn->instructionID = instructionID; insn->spec = specifierForUID(insn->instructionID); return 0; }
/* * readPrefixes - Consumes all of an instruction's prefix bytes, and marks the * instruction as having them. Also sets the instruction's default operand, * address, and other relevant data sizes to report operands correctly. * * @param insn - The instruction whose prefixes are to be read. * @return - 0 if the instruction could be read until the end of the prefix * bytes, and no prefixes conflicted; nonzero otherwise. */ static int readPrefixes(struct InternalInstruction* insn) { BOOL isPrefix = TRUE; BOOL prefixGroups[4] = { FALSE }; uint64_t prefixLocation; uint8_t byte = 0; BOOL hasAdSize = FALSE; BOOL hasOpSize = FALSE; dbgprintf(insn, "readPrefixes()"); while (isPrefix) { prefixLocation = insn->readerCursor; if (consumeByte(insn, &byte)) return -1; switch (byte) { case 0xf0: /* LOCK */ case 0xf2: /* REPNE/REPNZ */ case 0xf3: /* REP or REPE/REPZ */ if (prefixGroups[0]) dbgprintf(insn, "Redundant Group 1 prefix"); prefixGroups[0] = TRUE; setPrefixPresent(insn, byte, prefixLocation); break; case 0x2e: /* CS segment override -OR- Branch not taken */ case 0x36: /* SS segment override -OR- Branch taken */ case 0x3e: /* DS segment override */ case 0x26: /* ES segment override */ case 0x64: /* FS segment override */ case 0x65: /* GS segment override */ switch (byte) { case 0x2e: insn->segmentOverride = SEG_OVERRIDE_CS; break; case 0x36: insn->segmentOverride = SEG_OVERRIDE_SS; break; case 0x3e: insn->segmentOverride = SEG_OVERRIDE_DS; break; case 0x26: insn->segmentOverride = SEG_OVERRIDE_ES; break; case 0x64: insn->segmentOverride = SEG_OVERRIDE_FS; break; case 0x65: insn->segmentOverride = SEG_OVERRIDE_GS; break; default: debug("Unhandled override"); return -1; } if (prefixGroups[1]) dbgprintf(insn, "Redundant Group 2 prefix"); prefixGroups[1] = TRUE; setPrefixPresent(insn, byte, prefixLocation); break; case 0x66: /* Operand-size override */ if (prefixGroups[2]) dbgprintf(insn, "Redundant Group 3 prefix"); prefixGroups[2] = TRUE; hasOpSize = TRUE; setPrefixPresent(insn, byte, prefixLocation); break; case 0x67: /* Address-size override */ if (prefixGroups[3]) dbgprintf(insn, "Redundant Group 4 prefix"); prefixGroups[3] = TRUE; hasAdSize = TRUE; setPrefixPresent(insn, byte, prefixLocation); break; default: /* Not a prefix byte */ isPrefix = FALSE; break; } if (isPrefix) dbgprintf(insn, "Found prefix 0x%hhx", byte); } insn->vexSize = 0; if (byte == 0xc4) { uint8_t byte1; if (lookAtByte(insn, &byte1)) { dbgprintf(insn, "Couldn't read second byte of VEX"); return -1; } if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) { insn->vexSize = 3; insn->necessaryPrefixLocation = insn->readerCursor - 1; } else { unconsumeByte(insn); insn->necessaryPrefixLocation = insn->readerCursor - 1; } if (insn->vexSize == 3) { insn->vexPrefix[0] = byte; consumeByte(insn, &insn->vexPrefix[1]); consumeByte(insn, &insn->vexPrefix[2]); /* We simulate the REX prefix for simplicity's sake */ if (insn->mode == MODE_64BIT) { insn->rexPrefix = 0x40 | (wFromVEX3of3(insn->vexPrefix[2]) << 3) | (rFromVEX2of3(insn->vexPrefix[1]) << 2) | (xFromVEX2of3(insn->vexPrefix[1]) << 1) | (bFromVEX2of3(insn->vexPrefix[1]) << 0); } switch (ppFromVEX3of3(insn->vexPrefix[2])) { default: break; case VEX_PREFIX_66: hasOpSize = TRUE; break; } dbgprintf(insn, "Found VEX prefix 0x%hhx 0x%hhx 0x%hhx", insn->vexPrefix[0], insn->vexPrefix[1], insn->vexPrefix[2]); } } else if (byte == 0xc5) { uint8_t byte1; if (lookAtByte(insn, &byte1)) { dbgprintf(insn, "Couldn't read second byte of VEX"); return -1; } if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) { insn->vexSize = 2; } else { unconsumeByte(insn); } if (insn->vexSize == 2) { insn->vexPrefix[0] = byte; consumeByte(insn, &insn->vexPrefix[1]); if (insn->mode == MODE_64BIT) { insn->rexPrefix = 0x40 | (rFromVEX2of2(insn->vexPrefix[1]) << 2); } switch (ppFromVEX2of2(insn->vexPrefix[1])) { default: break; case VEX_PREFIX_66: hasOpSize = TRUE; break; } dbgprintf(insn, "Found VEX prefix 0x%hhx 0x%hhx", insn->vexPrefix[0], insn->vexPrefix[1]); } } else { if (insn->mode == MODE_64BIT) { if ((byte & 0xf0) == 0x40) { uint8_t opcodeByte; if (lookAtByte(insn, &opcodeByte) || ((opcodeByte & 0xf0) == 0x40)) { dbgprintf(insn, "Redundant REX prefix"); return -1; } insn->rexPrefix = byte; insn->necessaryPrefixLocation = insn->readerCursor - 2; dbgprintf(insn, "Found REX prefix 0x%hhx", byte); } else { unconsumeByte(insn); insn->necessaryPrefixLocation = insn->readerCursor - 1; } } else { unconsumeByte(insn); insn->necessaryPrefixLocation = insn->readerCursor - 1; } } if (insn->mode == MODE_16BIT) { insn->registerSize = (hasOpSize ? 4 : 2); insn->addressSize = (hasAdSize ? 4 : 2); insn->displacementSize = (hasAdSize ? 4 : 2); insn->immediateSize = (hasOpSize ? 4 : 2); } else if (insn->mode == MODE_32BIT) { insn->registerSize = (hasOpSize ? 2 : 4); insn->addressSize = (hasAdSize ? 2 : 4); insn->displacementSize = (hasAdSize ? 2 : 4); insn->immediateSize = (hasOpSize ? 2 : 4); } else if (insn->mode == MODE_64BIT) { if (insn->rexPrefix && wFromREX(insn->rexPrefix)) { insn->registerSize = 8; insn->addressSize = (hasAdSize ? 4 : 8); insn->displacementSize = 4; insn->immediateSize = 4; } else if (insn->rexPrefix) { insn->registerSize = (hasOpSize ? 2 : 4); insn->addressSize = (hasAdSize ? 4 : 8); insn->displacementSize = (hasOpSize ? 2 : 4); insn->immediateSize = (hasOpSize ? 2 : 4); } else { insn->registerSize = (hasOpSize ? 2 : 4); insn->addressSize = (hasAdSize ? 4 : 8); insn->displacementSize = (hasOpSize ? 2 : 4); insn->immediateSize = (hasOpSize ? 2 : 4); } } return 0; }
/* * readModRM - Consumes all addressing information (ModR/M byte, SIB byte, and * displacement) for an instruction and interprets it. * * @param insn - The instruction whose addressing information is to be read. * @return - 0 if the information was successfully read; nonzero otherwise. */ static int readModRM(struct InternalInstruction* insn) { uint8_t mod, rm, reg; dbgprintf(insn, "readModRM()"); if (insn->consumedModRM) return 0; if (consumeByte(insn, &insn->modRM)) return -1; insn->consumedModRM = TRUE; mod = modFromModRM(insn->modRM); rm = rmFromModRM(insn->modRM); reg = regFromModRM(insn->modRM); /* * This goes by insn->registerSize to pick the correct register, which messes * up if we're using (say) XMM or 8-bit register operands. That gets fixed in * fixupReg(). */ switch (insn->registerSize) { case 2: insn->regBase = MODRM_REG_AX; insn->eaRegBase = EA_REG_AX; break; case 4: insn->regBase = MODRM_REG_EAX; insn->eaRegBase = EA_REG_EAX; break; case 8: insn->regBase = MODRM_REG_RAX; insn->eaRegBase = EA_REG_RAX; break; } reg |= rFromREX(insn->rexPrefix) << 3; rm |= bFromREX(insn->rexPrefix) << 3; insn->reg = (Reg)(insn->regBase + reg); switch (insn->addressSize) { case 2: insn->eaBaseBase = EA_BASE_BX_SI; switch (mod) { case 0x0: if (rm == 0x6) { insn->eaBase = EA_BASE_NONE; insn->eaDisplacement = EA_DISP_16; if (readDisplacement(insn)) return -1; } else { insn->eaBase = (EABase)(insn->eaBaseBase + rm); insn->eaDisplacement = EA_DISP_NONE; } break; case 0x1: insn->eaBase = (EABase)(insn->eaBaseBase + rm); insn->eaDisplacement = EA_DISP_8; if (readDisplacement(insn)) return -1; break; case 0x2: insn->eaBase = (EABase)(insn->eaBaseBase + rm); insn->eaDisplacement = EA_DISP_16; if (readDisplacement(insn)) return -1; break; case 0x3: insn->eaBase = (EABase)(insn->eaRegBase + rm); if (readDisplacement(insn)) return -1; break; } break; case 4: case 8: insn->eaBaseBase = (insn->addressSize == 4 ? EA_BASE_EAX : EA_BASE_RAX); switch (mod) { case 0x0: insn->eaDisplacement = EA_DISP_NONE; /* readSIB may override this */ switch (rm) { case 0x4: case 0xc: /* in case REXW.b is set */ insn->eaBase = (insn->addressSize == 4 ? EA_BASE_sib : EA_BASE_sib64); readSIB(insn); if (readDisplacement(insn)) return -1; break; case 0x5: insn->eaBase = EA_BASE_NONE; insn->eaDisplacement = EA_DISP_32; if (readDisplacement(insn)) return -1; break; default: insn->eaBase = (EABase)(insn->eaBaseBase + rm); break; } break; case 0x1: case 0x2: insn->eaDisplacement = (mod == 0x1 ? EA_DISP_8 : EA_DISP_32); switch (rm) { case 0x4: case 0xc: /* in case REXW.b is set */ insn->eaBase = EA_BASE_sib; readSIB(insn); if (readDisplacement(insn)) return -1; break; default: insn->eaBase = (EABase)(insn->eaBaseBase + rm); if (readDisplacement(insn)) return -1; break; } break; case 0x3: insn->eaDisplacement = EA_DISP_NONE; insn->eaBase = (EABase)(insn->eaRegBase + rm); break; } break; } /* switch (insn->addressSize) */ return 0; }
/* * readOperands - Consults the specifier for an instruction and consumes all * operands for that instruction, interpreting them as it goes. * * @param insn - The instruction whose operands are to be read and interpreted. * @return - 0 if all operands could be read; nonzero otherwise. */ static int readOperands(struct InternalInstruction* insn) { int index; int hasVVVV, needVVVV; int sawRegImm = 0; dbgprintf(insn, "readOperands()"); /* If non-zero vvvv specified, need to make sure one of the operands uses it. */ hasVVVV = !readVVVV(insn); needVVVV = hasVVVV && (insn->vvvv != 0); for (index = 0; index < X86_MAX_OPERANDS; ++index) { switch (insn->spec->operands[index].encoding) { case ENCODING_NONE: break; case ENCODING_REG: case ENCODING_RM: if (readModRM(insn)) return -1; if (fixupReg(insn, &insn->spec->operands[index])) return -1; break; case ENCODING_CB: case ENCODING_CW: case ENCODING_CD: case ENCODING_CP: case ENCODING_CO: case ENCODING_CT: dbgprintf(insn, "We currently don't hande code-offset encodings"); return -1; case ENCODING_IB: if (sawRegImm) { /* Saw a register immediate so don't read again and instead split the previous immediate. FIXME: This is a hack. */ insn->immediates[insn->numImmediatesConsumed] = insn->immediates[insn->numImmediatesConsumed - 1] & 0xf; ++insn->numImmediatesConsumed; break; } if (readImmediate(insn, 1)) return -1; if (insn->spec->operands[index].type == TYPE_IMM3 && insn->immediates[insn->numImmediatesConsumed - 1] > 7) return -1; if (insn->spec->operands[index].type == TYPE_XMM128 || insn->spec->operands[index].type == TYPE_XMM256) sawRegImm = 1; break; case ENCODING_IW: if (readImmediate(insn, 2)) return -1; break; case ENCODING_ID: if (readImmediate(insn, 4)) return -1; break; case ENCODING_IO: if (readImmediate(insn, 8)) return -1; break; case ENCODING_Iv: if (readImmediate(insn, insn->immediateSize)) return -1; break; case ENCODING_Ia: if (readImmediate(insn, insn->addressSize)) return -1; break; case ENCODING_RB: if (readOpcodeRegister(insn, 1)) return -1; break; case ENCODING_RW: if (readOpcodeRegister(insn, 2)) return -1; break; case ENCODING_RD: if (readOpcodeRegister(insn, 4)) return -1; break; case ENCODING_RO: if (readOpcodeRegister(insn, 8)) return -1; break; case ENCODING_Rv: if (readOpcodeRegister(insn, 0)) return -1; break; case ENCODING_I: if (readOpcodeModifier(insn)) return -1; break; case ENCODING_VVVV: needVVVV = 0; /* Mark that we have found a VVVV operand. */ if (!hasVVVV) return -1; if (fixupReg(insn, &insn->spec->operands[index])) return -1; break; case ENCODING_DUP: break; default: dbgprintf(insn, "Encountered an operand with an unknown encoding."); return -1; } } /* If we didn't find ENCODING_VVVV operand, but non-zero vvvv present, fail */ if (needVVVV) return -1; return 0; }
void add_http_test(testitem_t *t) { http_data_t *httptest; char *dnsip = NULL; ssloptions_t *sslopt = NULL; char *sslopt_ciphers = NULL; int sslopt_version = SSLVERSION_DEFAULT; char *sslopt_clientcert = NULL; int httpversion = HTTPVER_11; cookielist_t *ck = NULL; int firstcookie = 1; char *decodedurl; strbuffer_t *httprequest = newstrbuffer(0); /* Allocate the private data and initialize it */ httptest = (http_data_t *) calloc(1, sizeof(http_data_t)); t->privdata = (void *) httptest; decodedurl = decode_url(t->testspec, &httptest->weburl); if (!decodedurl) { errprintf("Invalid URL for http check: %s\n", t->testspec); return; } httptest->url = strdup(decodedurl); httptest->contlen = -1; httptest->parsestatus = (httptest->weburl.proxyurl ? httptest->weburl.proxyurl->parseerror : httptest->weburl.desturl->parseerror); /* If there was a parse error in the URL, dont run the test */ if (httptest->parsestatus) return; if (httptest->weburl.proxyurl && (httptest->weburl.proxyurl->ip == NULL)) { dnsip = dnsresolve(httptest->weburl.proxyurl->host); if (dnsip) { httptest->weburl.proxyurl->ip = strdup(dnsip); } else { dbgprintf("Could not resolve URL hostname '%s'\n", httptest->weburl.proxyurl->host); } } else if (httptest->weburl.desturl->ip == NULL) { dnsip = dnsresolve(httptest->weburl.desturl->host); if (dnsip) { httptest->weburl.desturl->ip = strdup(dnsip); } else { dbgprintf("Could not resolve URL hostname '%s'\n", httptest->weburl.desturl->host); } } switch (httptest->weburl.testtype) { case WEBTEST_PLAIN: case WEBTEST_STATUS: httptest->contentcheck = CONTENTCHECK_NONE; break; case WEBTEST_CONTENT: { FILE *contentfd; char contentfn[PATH_MAX]; sprintf(contentfn, "%s/content/%s.substring", xgetenv("XYMONHOME"), commafy(t->host->hostname)); contentfd = fopen(contentfn, "r"); if (contentfd) { char l[MAX_LINE_LEN]; char *p; if (fgets(l, sizeof(l), contentfd)) { p = strchr(l, '\n'); if (p) { *p = '\0'; }; httptest->weburl.expdata = strdup(l); } else { httptest->contstatus = STATUS_CONTENTMATCH_NOFILE; } fclose(contentfd); } else { httptest->contstatus = STATUS_CONTENTMATCH_NOFILE; } httptest->contentcheck = CONTENTCHECK_REGEX; } break; case WEBTEST_CONT: httptest->contentcheck = ((*httptest->weburl.expdata == '#') ? CONTENTCHECK_DIGEST : CONTENTCHECK_REGEX); break; case WEBTEST_NOCONT: httptest->contentcheck = CONTENTCHECK_NOREGEX; break; case WEBTEST_POST: case WEBTEST_SOAP: if (httptest->weburl.expdata == NULL) { httptest->contentcheck = CONTENTCHECK_NONE; } else { httptest->contentcheck = ((*httptest->weburl.expdata == '#') ? CONTENTCHECK_DIGEST : CONTENTCHECK_REGEX); } break; case WEBTEST_NOPOST: case WEBTEST_NOSOAP: if (httptest->weburl.expdata == NULL) { httptest->contentcheck = CONTENTCHECK_NONE; } else { httptest->contentcheck = CONTENTCHECK_NOREGEX; } break; case WEBTEST_TYPE: httptest->contentcheck = CONTENTCHECK_CONTENTTYPE; break; } /* Compile the hashes and regex's for those tests that use it */ switch (httptest->contentcheck) { case CONTENTCHECK_DIGEST: { char *hashfunc; httptest->exp = (void *) strdup(httptest->weburl.expdata+1); hashfunc = strchr(httptest->exp, ':'); if (hashfunc) { *hashfunc = '\0'; httptest->digestctx = digest_init(httptest->exp); *hashfunc = ':'; } } break; case CONTENTCHECK_REGEX: case CONTENTCHECK_NOREGEX: { int status; httptest->exp = (void *) malloc(sizeof(regex_t)); status = regcomp((regex_t *)httptest->exp, httptest->weburl.expdata, REG_EXTENDED|REG_NOSUB); if (status) { errprintf("Failed to compile regexp '%s' for URL %s\n", httptest->weburl.expdata, httptest->url); httptest->contstatus = STATUS_CONTENTMATCH_BADREGEX; } } break; case CONTENTCHECK_CONTENTTYPE: httptest->exp = httptest->weburl.expdata; break; } if (httptest->weburl.desturl->schemeopts) { if (strstr(httptest->weburl.desturl->schemeopts, "3")) sslopt_version = SSLVERSION_V3; else if (strstr(httptest->weburl.desturl->schemeopts, "2")) sslopt_version = SSLVERSION_V2; if (strstr(httptest->weburl.desturl->schemeopts, "h")) sslopt_ciphers = ciphershigh; else if (strstr(httptest->weburl.desturl->schemeopts, "m")) sslopt_ciphers = ciphersmedium; if (strstr(httptest->weburl.desturl->schemeopts, "10")) httpversion = HTTPVER_10; else if (strstr(httptest->weburl.desturl->schemeopts, "11")) httpversion = HTTPVER_11; } /* Get any cookies */ load_cookies(); /* Generate the request */ addtobuffer(httprequest, (httptest->weburl.postdata ? "POST " : "GET ")); switch (httpversion) { case HTTPVER_10: addtobuffer(httprequest, (httptest->weburl.proxyurl ? httptest->url : httptest->weburl.desturl->relurl)); addtobuffer(httprequest, " HTTP/1.0\r\n"); break; case HTTPVER_11: /* * Experience shows that even though HTTP/1.1 says you should send the * full URL, some servers (e.g. SunOne App server 7) choke on it. * So just send the good-old relative URL unless we're proxying. */ addtobuffer(httprequest, (httptest->weburl.proxyurl ? httptest->url : httptest->weburl.desturl->relurl)); addtobuffer(httprequest, " HTTP/1.1\r\n"); addtobuffer(httprequest, "Connection: close\r\n"); break; } addtobuffer(httprequest, "Host: "); addtobuffer(httprequest, httptest->weburl.desturl->host); if ((httptest->weburl.desturl->port != 80) && (httptest->weburl.desturl->port != 443)) { char hostporthdr[20]; sprintf(hostporthdr, ":%d", httptest->weburl.desturl->port); addtobuffer(httprequest, hostporthdr); } addtobuffer(httprequest, "\r\n"); if (httptest->weburl.postdata) { char hdr[100]; int contlen = strlen(httptest->weburl.postdata); if (strncmp(httptest->weburl.postdata, "file:", 5) == 0) { /* Load the POST data from a file */ FILE *pf = fopen(httptest->weburl.postdata+5, "r"); if (pf == NULL) { errprintf("Cannot open POST data file %s\n", httptest->weburl.postdata+5); xfree(httptest->weburl.postdata); httptest->weburl.postdata = strdup(""); contlen = 0; } else { struct stat st; if (fstat(fileno(pf), &st) == 0) { int n; xfree(httptest->weburl.postdata); httptest->weburl.postdata = (char *)malloc(st.st_size + 1); *(httptest->weburl.postdata) = '\0'; n = fread(httptest->weburl.postdata, 1, st.st_size, pf); if (n == st.st_size) { *(httptest->weburl.postdata+n) = '\0'; contlen = n; } else { errprintf("Cannot read file %s: %s\n", httptest->weburl.postdata+5, strerror(errno)); contlen = 0; } } else { errprintf("Cannot stat file %s\n", httptest->weburl.postdata+5); httptest->weburl.postdata = strdup(""); contlen = 0; } fclose(pf); } } addtobuffer(httprequest, "Content-type: "); if (httptest->weburl.postcontenttype) addtobuffer(httprequest, httptest->weburl.postcontenttype); else if ((httptest->weburl.testtype == WEBTEST_SOAP) || (httptest->weburl.testtype == WEBTEST_NOSOAP)) addtobuffer(httprequest, "application/soap+xml; charset=utf-8"); else addtobuffer(httprequest, "application/x-www-form-urlencoded"); addtobuffer(httprequest, "\r\n"); sprintf(hdr, "Content-Length: %d\r\n", contlen); addtobuffer(httprequest, hdr); } { char useragent[100]; void *hinfo; char *browser = NULL; hinfo = hostinfo(t->host->hostname); if (hinfo) browser = xmh_item(hinfo, XMH_BROWSER); if (browser) { sprintf(useragent, "User-Agent: %s\r\n", browser); } else { sprintf(useragent, "User-Agent: Xymon xymonnet/%s\r\n", VERSION); } addtobuffer(httprequest, useragent); } if (httptest->weburl.desturl->auth) { if (strncmp(httptest->weburl.desturl->auth, "CERT:", 5) == 0) { sslopt_clientcert = httptest->weburl.desturl->auth+5; } else { addtobuffer(httprequest, "Authorization: Basic "); addtobuffer(httprequest, base64encode(httptest->weburl.desturl->auth)); addtobuffer(httprequest, "\r\n"); } } if (httptest->weburl.proxyurl && httptest->weburl.proxyurl->auth) { addtobuffer(httprequest, "Proxy-Authorization: Basic "); addtobuffer(httprequest, base64encode(httptest->weburl.proxyurl->auth)); addtobuffer(httprequest, "\r\n"); } for (ck = cookiehead; (ck); ck = ck->next) { int useit = 0; if (ck->tailmatch) { int startpos = strlen(httptest->weburl.desturl->host) - strlen(ck->host); if (startpos > 0) useit = (strcmp(httptest->weburl.desturl->host+startpos, ck->host) == 0); } else useit = (strcmp(httptest->weburl.desturl->host, ck->host) == 0); if (useit) useit = (strncmp(ck->path, httptest->weburl.desturl->relurl, strlen(ck->path)) == 0); if (useit) { if (firstcookie) { addtobuffer(httprequest, "Cookie: "); firstcookie = 0; } addtobuffer(httprequest, ck->name); addtobuffer(httprequest, "="); addtobuffer(httprequest, ck->value); addtobuffer(httprequest, "\r\n"); } } /* Some standard stuff */ addtobuffer(httprequest, "Accept: */*\r\n"); addtobuffer(httprequest, "Pragma: no-cache\r\n"); if ((httptest->weburl.testtype == WEBTEST_SOAP) || (httptest->weburl.testtype == WEBTEST_NOSOAP)) { /* Must provide a SOAPAction header */ addtobuffer(httprequest, "SOAPAction: "); addtobuffer(httprequest, httptest->url); addtobuffer(httprequest, "\r\n"); } /* The final blank line terminates the headers */ addtobuffer(httprequest, "\r\n"); /* Post data goes last */ if (httptest->weburl.postdata) addtobuffer(httprequest, httptest->weburl.postdata); /* Pickup any SSL options the user wants */ if (sslopt_ciphers || (sslopt_version != SSLVERSION_DEFAULT) || sslopt_clientcert){ sslopt = (ssloptions_t *) malloc(sizeof(ssloptions_t)); sslopt->cipherlist = sslopt_ciphers; sslopt->sslversion = sslopt_version; sslopt->clientcert = sslopt_clientcert; } /* Add to TCP test queue */ if (httptest->weburl.proxyurl == NULL) { httptest->tcptest = add_tcp_test(httptest->weburl.desturl->ip, httptest->weburl.desturl->port, httptest->weburl.desturl->scheme, sslopt, t->srcip, t->testspec, t->silenttest, grabstrbuffer(httprequest), httptest, tcp_http_data_callback, tcp_http_final_callback); } else { httptest->tcptest = add_tcp_test(httptest->weburl.proxyurl->ip, httptest->weburl.proxyurl->port, httptest->weburl.proxyurl->scheme, sslopt, t->srcip, t->testspec, t->silenttest, grabstrbuffer(httprequest), httptest, tcp_http_data_callback, tcp_http_final_callback); } }
/* * readOpcode - Reads the opcode (excepting the ModR/M byte in the case of * extended or escape opcodes). * * @param insn - The instruction whose opcode is to be read. * @return - 0 if the opcode could be read successfully; nonzero otherwise. */ static int readOpcode(struct InternalInstruction* insn) { /* Determine the length of the primary opcode */ uint8_t current; dbgprintf(insn, "readOpcode()"); insn->opcodeType = ONEBYTE; if (insn->vexSize == 3) { switch (mmmmmFromVEX2of3(insn->vexPrefix[1])) { default: dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)", mmmmmFromVEX2of3(insn->vexPrefix[1])); return -1; case 0: break; case VEX_LOB_0F: insn->twoByteEscape = 0x0f; insn->opcodeType = TWOBYTE; return consumeByte(insn, &insn->opcode); case VEX_LOB_0F38: insn->twoByteEscape = 0x0f; insn->threeByteEscape = 0x38; insn->opcodeType = THREEBYTE_38; return consumeByte(insn, &insn->opcode); case VEX_LOB_0F3A: insn->twoByteEscape = 0x0f; insn->threeByteEscape = 0x3a; insn->opcodeType = THREEBYTE_3A; return consumeByte(insn, &insn->opcode); } } else if (insn->vexSize == 2) { insn->twoByteEscape = 0x0f; insn->opcodeType = TWOBYTE; return consumeByte(insn, &insn->opcode); } if (consumeByte(insn, ¤t)) return -1; if (current == 0x0f) { dbgprintf(insn, "Found a two-byte escape prefix (0x%hhx)", current); insn->twoByteEscape = current; if (consumeByte(insn, ¤t)) return -1; if (current == 0x38) { dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current); insn->threeByteEscape = current; if (consumeByte(insn, ¤t)) return -1; insn->opcodeType = THREEBYTE_38; } else if (current == 0x3a) { dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current); insn->threeByteEscape = current; if (consumeByte(insn, ¤t)) return -1; insn->opcodeType = THREEBYTE_3A; } else if (current == 0xa6) { dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current); insn->threeByteEscape = current; if (consumeByte(insn, ¤t)) return -1; insn->opcodeType = THREEBYTE_A6; } else if (current == 0xa7) { dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current); insn->threeByteEscape = current; if (consumeByte(insn, ¤t)) return -1; insn->opcodeType = THREEBYTE_A7; } else { dbgprintf(insn, "Didn't find a three-byte escape prefix"); insn->opcodeType = TWOBYTE; } } /* * At this point we have consumed the full opcode. * Anything we consume from here on must be unconsumed. */ insn->opcode = current; return 0; }
int tcp_http_data_callback(unsigned char *buf, unsigned int len, void *priv) { /* * This callback receives data from HTTP servers. * While doing that, it splits out the data into a * buffer for the HTTP headers, and a buffer for the * HTTP content-data. * Return 1 if data is complete, 0 if more data wanted. */ http_data_t *item = (http_data_t *) priv; if (item->gotheaders) { unsigned int len1chunk = 0; int i; /* * We already have the headers, so just stash away the data */ while (len > 0) { dbgprintf("HDC IN : state=%d, leftinchunk=%d, len=%d\n", item->chunkstate, item->leftinchunk, len); switch (item->chunkstate) { case CHUNK_NOTCHUNKED: len1chunk = len; if ((item->contlen > 0) && (item->contlen >= len)) item->contlen -= len; break; case CHUNK_INIT: /* We're about to pick up a chunk length */ item->leftinchunk = 0; item->chunkstate = CHUNK_GETLEN; len1chunk = 0; break; case CHUNK_GETLEN: /* We are collecting the length of the chunk */ i = hexvalue(*buf); if (i == -1) { item->chunkstate = CHUNK_SKIPLENCR; } else { item->leftinchunk = item->leftinchunk*16 + i; buf++; len--; } len1chunk = 0; break; case CHUNK_SKIPLENCR: /* We've got the length, now skip to the next LF */ if (*buf == '\n') { buf++; len--; item->chunkstate = ((item->leftinchunk > 0) ? CHUNK_DATA : CHUNK_NOMORE); } else if ((*buf == '\r') || (*buf == ' ')) { buf++; len--; } else { errprintf("Yikes - strange data following chunk len. Saw a '%c'\n", *buf); buf++; len--; } len1chunk = 0; break; case CHUNK_DATA: /* Passing off the data */ if (len > item->leftinchunk) len1chunk = item->leftinchunk; else len1chunk = len; item->leftinchunk -= len1chunk; if (item->leftinchunk == 0) item->chunkstate = CHUNK_SKIPENDCR; break; case CHUNK_SKIPENDCR: /* Skip CR/LF after a chunk */ if (*buf == '\n') { buf++; len--; item->chunkstate = CHUNK_DONE; } else if (*buf == '\r') { buf++; len--; } else { errprintf("Yikes - strange data following chunk data. Saw a '%c'\n", *buf); buf++; len--; } len1chunk = 0; break; case CHUNK_DONE: /* One chunk is done, continue with the next */ len1chunk = 0; item->chunkstate = CHUNK_GETLEN; break; case CHUNK_NOMORE: /* All chunks done. Skip the rest (trailers) */ len1chunk = 0; len = 0; } if (len1chunk > 0) { switch (item->contentcheck) { case CONTENTCHECK_NONE: case CONTENTCHECK_CONTENTTYPE: /* No need to save output - just drop it */ break; case CONTENTCHECK_REGEX: case CONTENTCHECK_NOREGEX: /* Save the full data */ if ((item->output == NULL) || (item->outlen == 0)) { item->output = (unsigned char *)malloc(len1chunk+1); } else { item->output = (unsigned char *)realloc(item->output, item->outlen+len1chunk+1); } memcpy(item->output+item->outlen, buf, len1chunk); item->outlen += len1chunk; *(item->output + item->outlen) = '\0'; /* Just in case ... */ break; case CONTENTCHECK_DIGEST: /* Run the data through our digest routine, but discard the raw data */ if ((item->digestctx == NULL) || (digest_data(item->digestctx, buf, len1chunk) != 0)) { errprintf("Failed to hash data for digest\n"); } break; } buf += len1chunk; len -= len1chunk; dbgprintf("HDC OUT: state=%d, leftinchunk=%d, len=%d\n", item->chunkstate, item->leftinchunk, len); } } } else { /* * Havent seen the end of headers yet. */ unsigned char *p; /* First, add this to the header-buffer */ if (item->headers == NULL) { item->headers = (unsigned char *) malloc(len+1); } else { item->headers = (unsigned char *) realloc(item->headers, item->hdrlen+len+1); } memcpy(item->headers+item->hdrlen, buf, len); item->hdrlen += len; *(item->headers + item->hdrlen) = '\0'; check_for_endofheaders: /* * Now see if we have the end-of-headers delimiter. * This SHOULD be <cr><lf><cr><lf>, but RFC 2616 says * you SHOULD recognize just plain <lf><lf>. * So try the second form, if the first one is not there. */ p=strstr(item->headers, "\r\n\r\n"); if (p) { p += 4; } else { p = strstr(item->headers, "\n\n"); if (p) p += 2; } if (p) { int http1subver, httpstatus; unsigned int bytesindata; char *p1, *xferencoding; int contlen; /* We have an end-of-header delimiter, but it could be just a "100 Continue" response */ sscanf(item->headers, "HTTP/1.%d %d", &http1subver, &httpstatus); if (httpstatus == 100) { /* * It's a "100" continue-status. * Just drop this set of headers, and move on. */ item->hdrlen -= (p - item->headers); if (item->hdrlen > 0) { memmove(item->headers, p, item->hdrlen); *(item->headers + item->hdrlen) = '\0'; goto check_for_endofheaders; } else { xfree(item->headers); item->headers = NULL; item->hdrlen = 0; return 0; } /* Should never go here ... */ } /* We did find the end-of-header delimiter, and it is not a "100" status. */ item->gotheaders = 1; /* p points at the first byte of DATA. So the header ends 1 or 2 bytes before. */ *(p-1) = '\0'; if (*(p-2) == '\r') { *(p-2) = '\0'; } /* NULL-terminate the headers. */ /* See if the transfer uses chunks */ p1 = item->headers; xferencoding = NULL; contlen = 0; do { if (strncasecmp(p1, "Transfer-encoding:", 18) == 0) { p1 += 18; while (isspace((int)*p1)) p1++; xferencoding = p1; } else if (strncasecmp(p1, "Content-Length:", 15) == 0) { p1 += 15; while (isspace((int)*p1)) p1++; contlen = atoi(p1); } else { p1 = strchr(p1, '\n'); if (p1) p1++; } } while (p1 && (xferencoding == NULL)); if (xferencoding && (strncasecmp(xferencoding, "chunked", 7) == 0)) { item->chunkstate = CHUNK_INIT; } item->contlen = (contlen ? contlen : -1); bytesindata = item->hdrlen - (p - item->headers); item->hdrlen = strlen(item->headers); if (*p) { /* * We received some content data together with the * headers. Save these to the content-data area. */ tcp_http_data_callback(p, bytesindata, priv); } } } if (item->chunkstate == CHUNK_NOTCHUNKED) /* Not chunked - we're done if contlen reaches 0 */ return (item->contlen == 0); else /* Chunked - we're done if we reach state NOMORE*/ return (item->chunkstate == CHUNK_NOMORE); }
/* * readSIB - Consumes the SIB byte to determine addressing information for an * instruction. * * @param insn - The instruction whose SIB byte is to be read. * @return - 0 if the SIB byte was successfully read; nonzero otherwise. */ static int readSIB(struct InternalInstruction* insn) { SIBIndex sibIndexBase = 0; SIBBase sibBaseBase = 0; uint8_t index, base; dbgprintf(insn, "readSIB()"); if (insn->consumedSIB) return 0; insn->consumedSIB = TRUE; switch (insn->addressSize) { case 2: dbgprintf(insn, "SIB-based addressing doesn't work in 16-bit mode"); return -1; break; case 4: sibIndexBase = SIB_INDEX_EAX; sibBaseBase = SIB_BASE_EAX; break; case 8: sibIndexBase = SIB_INDEX_RAX; sibBaseBase = SIB_BASE_RAX; break; } if (consumeByte(insn, &insn->sib)) return -1; index = indexFromSIB(insn->sib) | (xFromREX(insn->rexPrefix) << 3); switch (index) { case 0x4: insn->sibIndex = SIB_INDEX_NONE; break; default: insn->sibIndex = (SIBIndex)(sibIndexBase + index); if (insn->sibIndex == SIB_INDEX_sib || insn->sibIndex == SIB_INDEX_sib64) insn->sibIndex = SIB_INDEX_NONE; break; } switch (scaleFromSIB(insn->sib)) { case 0: insn->sibScale = 1; break; case 1: insn->sibScale = 2; break; case 2: insn->sibScale = 4; break; case 3: insn->sibScale = 8; break; } base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3); switch (base) { case 0x5: switch (modFromModRM(insn->modRM)) { case 0x0: insn->eaDisplacement = EA_DISP_32; insn->sibBase = SIB_BASE_NONE; break; case 0x1: insn->eaDisplacement = EA_DISP_8; insn->sibBase = (insn->addressSize == 4 ? SIB_BASE_EBP : SIB_BASE_RBP); break; case 0x2: insn->eaDisplacement = EA_DISP_32; insn->sibBase = (insn->addressSize == 4 ? SIB_BASE_EBP : SIB_BASE_RBP); break; case 0x3: debug("Cannot have Mod = 0b11 and a SIB byte"); return -1; } break; default: insn->sibBase = (SIBBase)(sibBaseBase + base); break; } return 0; }
void send_summaries(summary_t *sumhead) { summary_t *s; for (s = sumhead; (s); s = s->next) { char *suburl; int summarycolor = -1; char *summsg; /* Decide which page to pick the color from for this summary. */ suburl = s->url; if (strncmp(suburl, "http://", 7) == 0) { char *p; /* Skip hostname part */ suburl += 7; /* Skip "http://" */ p = strchr(suburl, '/'); /* Find next '/' */ if (p) suburl = p; } if (strncmp(suburl, xgetenv("XYMONWEB"), strlen(xgetenv("XYMONWEB"))) == 0) suburl += strlen(xgetenv("XYMONWEB")); if (*suburl == '/') suburl++; dbgprintf("summ1: s->url=%s, suburl=%s\n", s->url, suburl); if (strcmp(suburl, "xymon.html") == 0) summarycolor = xymon_color; else if (strcmp(suburl, "index.html") == 0) summarycolor = xymon_color; else if (strcmp(suburl, "") == 0) summarycolor = xymon_color; else if (strcmp(suburl, "nongreen.html") == 0) summarycolor = nongreen_color; else if (strcmp(suburl, "critical.html") == 0) summarycolor = critical_color; else { /* * Specific page - find it in the page tree. */ char *p, *pg; xymongen_page_t *pgwalk; xymongen_page_t *sourcepg = NULL; char *urlcopy = strdup(suburl); /* * Walk the page tree */ pg = urlcopy; sourcepg = pagehead; do { p = strchr(pg, '/'); if (p) *p = '\0'; dbgprintf("Searching for page %s\n", pg); for (pgwalk = sourcepg->subpages; (pgwalk && (strcmp(pgwalk->name, pg) != 0)); pgwalk = pgwalk->next); if (pgwalk != NULL) { sourcepg = pgwalk; if (p) { *p = '/'; pg = p+1; } else pg = NULL; } else pg = NULL; } while (pg); dbgprintf("Summary search for %s found page %s (title:%s), color %d\n", suburl, sourcepg->name, sourcepg->title, sourcepg->color); summarycolor = sourcepg->color; xfree(urlcopy); } if (summarycolor == -1) { errprintf("Could not determine sourcepage for summary %s\n", s->url); summarycolor = pagehead->color; } /* Send the summary message */ summsg = (char *)malloc(1024 + strlen(s->name) + strlen(s->url) + strlen(timestamp)); sprintf(summsg, "summary summary.%s %s %s %s", s->name, colorname(summarycolor), s->url, timestamp); sendmessage(summsg, s->receiver, XYMON_TIMEOUT, NULL); xfree(summsg); } }
int do_external_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { pid_t childpid; dbgprintf("-> do_external(%s, %s)\n", hostname, testname); childpid = fork(); if (childpid == 0) { FILE *fd; char fn[PATH_MAX]; enum { R_DEFS, R_FN, R_DATA, R_NEXT } pstate; FILE *extfd; char extcmd[2*PATH_MAX]; strbuffer_t *inbuf; char *p; char **params = NULL; int paridx = 0; pid_t mypid = getpid(); MEMDEFINE(fn); MEMDEFINE(extcmd); sprintf(fn, "%s/rrd_msg_%d", xgetenv("XYMONTMP"), (int) getpid()); dbgprintf("%09d : Saving msg to file %s\n", (int)mypid, fn); fd = fopen(fn, "w"); if (fd == NULL) { errprintf("Cannot create temp file %s\n", fn); exit(1); } if (fwrite(msg, strlen(msg), 1, fd) != 1) { errprintf("Error writing to file %s: %s\n", fn, strerror(errno)); exit(1) ; } if (fclose(fd)) errprintf("Error closing file %s: %s\n", fn, strerror(errno)); /* * Disable the RRD update cache. * We cannot use the cache, because this child * process terminates without flushing the cache, * and it cannot feed the update-data back to the * parent process which owns the cache. So using * an external handler means the updates will be * sync'ed to disk immediately. * * NB: It is OK to do this now and not re-enable it, * since we're running in the external helper * child process - so this only affects the current * update. * * Thanks to Graham Nayler for the analysis. */ use_rrd_cache = 0; inbuf = newstrbuffer(0); /* Now call the external helper */ sprintf(extcmd, "%s %s %s %s", exthandler, hostname, testname, fn); dbgprintf("%09d : Calling helper script %s\n", (int)mypid, extcmd); extfd = popen(extcmd, "r"); if (extfd) { pstate = R_DEFS; initfgets(extfd); while (unlimfgets(inbuf, extfd)) { p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0'; dbgprintf("%09d : Helper input '%s'\n", (int)mypid, STRBUF(inbuf)); if (STRBUFLEN(inbuf) == 0) continue; if (pstate == R_NEXT) { /* After doing one set of data, allow script to re-use the same DS defs */ if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) { /* New DS definitions, scratch the old ones */ if (params) { for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); xfree(params); params = NULL; } pstate = R_DEFS; } else pstate = R_FN; } switch (pstate) { case R_DEFS: if (params == NULL) { params = (char **)calloc(1, sizeof(char *)); paridx = 0; } if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) { /* Dataset definition */ params[paridx] = strdup(STRBUF(inbuf)); paridx++; params = (char **)realloc(params, (1 + paridx)*sizeof(char *)); params[paridx] = NULL; break; } else { /* No more DS defs */ pstate = R_FN; } /* Fall through */ case R_FN: setupfn("%s", STRBUF(inbuf)); pstate = R_DATA; break; case R_DATA: snprintf(rrdvalues, sizeof(rrdvalues)-1, "%d:%s", (int)tstamp, STRBUF(inbuf)); rrdvalues[sizeof(rrdvalues)-1] = '\0'; create_and_update_rrd(hostname, testname, classname, pagepaths, params, NULL); pstate = R_NEXT; break; case R_NEXT: /* Should not happen */ break; } } pclose(extfd); } else { errprintf("Pipe open of RRD handler failed: %s\n", strerror(errno)); } if (params) { for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); xfree(params); } dbgprintf("%09d : Unlinking temp file\n", (int)mypid); unlink(fn); freestrbuffer(inbuf); exit(0); } else if (childpid > 0) { /* Parent continues */ } else { errprintf("Fork failed in RRD handler: %s\n", strerror(errno)); } dbgprintf("<- do_external(%s, %s)\n", hostname, testname); return 0; }
/* * getID - Determines the ID of an instruction, consuming the ModR/M byte as * appropriate for extended and escape opcodes. Determines the attributes and * context for the instruction before doing so. * * @param insn - The instruction whose ID is to be determined. * @return - 0 if the ModR/M could be read when needed or was not needed; * nonzero otherwise. */ static int getID(struct InternalInstruction* insn) { uint8_t attrMask; uint16_t instructionID; dbgprintf(insn, "getID()"); attrMask = ATTR_NONE; if (insn->mode == MODE_64BIT) attrMask |= ATTR_64BIT; if (insn->vexSize) { attrMask |= ATTR_VEX; if (insn->vexSize == 3) { switch (ppFromVEX3of3(insn->vexPrefix[2])) { case VEX_PREFIX_66: attrMask |= ATTR_OPSIZE; break; case VEX_PREFIX_F3: attrMask |= ATTR_XS; break; case VEX_PREFIX_F2: attrMask |= ATTR_XD; break; } if (wFromVEX3of3(insn->vexPrefix[2])) attrMask |= ATTR_REXW; if (lFromVEX3of3(insn->vexPrefix[2])) attrMask |= ATTR_VEXL; } else if (insn->vexSize == 2) { switch (ppFromVEX2of2(insn->vexPrefix[1])) { case VEX_PREFIX_66: attrMask |= ATTR_OPSIZE; break; case VEX_PREFIX_F3: attrMask |= ATTR_XS; break; case VEX_PREFIX_F2: attrMask |= ATTR_XD; break; } if (lFromVEX2of2(insn->vexPrefix[1])) attrMask |= ATTR_VEXL; } else { return -1; } } else { if (insn->rexPrefix & 0x08) attrMask |= ATTR_REXW; if (isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) attrMask |= ATTR_OPSIZE; else if (isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation)) attrMask |= ATTR_XS; else if (isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation)) attrMask |= ATTR_XD; } if (getIDWithAttrMask(&instructionID, insn, attrMask)) return -1; /* The following clauses compensate for limitations of the tables. */ if ((attrMask & ATTR_XD) && (attrMask & ATTR_REXW)) { /* * Although for SSE instructions it is usually necessary to treat REX.W+F2 * as F2 for decode (in the absence of a 64BIT_REXW_XD category) there is * an occasional instruction where F2 is incidental and REX.W is the more * significant. If the decoded instruction is 32-bit and adding REX.W * instead of F2 changes a 32 to a 64, we adopt the new encoding. */ const struct InstructionSpecifier *spec; uint16_t instructionIDWithREXw; const struct InstructionSpecifier *specWithREXw; spec = specifierForUID(instructionID); if (getIDWithAttrMask(&instructionIDWithREXw, insn, attrMask & (~ATTR_XD))) { /* * Decoding with REX.w would yield nothing; give up and return original * decode. */ insn->instructionID = instructionID; insn->spec = spec; return 0; } specWithREXw = specifierForUID(instructionIDWithREXw); if (is64BitEquivalent(spec->name, specWithREXw->name)) { insn->instructionID = instructionIDWithREXw; insn->spec = specWithREXw; } else { insn->instructionID = instructionID; insn->spec = spec; } return 0; } if (insn->prefixPresent[0x66] && !(attrMask & ATTR_OPSIZE)) { /* * The instruction tables make no distinction between instructions that * allow OpSize anywhere (i.e., 16-bit operations) and that need it in a * particular spot (i.e., many MMX operations). In general we're * conservative, but in the specific case where OpSize is present but not * in the right place we check if there's a 16-bit operation. */ const struct InstructionSpecifier *spec; uint16_t instructionIDWithOpsize; const struct InstructionSpecifier *specWithOpsize; spec = specifierForUID(instructionID); if (getIDWithAttrMask(&instructionIDWithOpsize, insn, attrMask | ATTR_OPSIZE)) { /* * ModRM required with OpSize but not present; give up and return version * without OpSize set */ insn->instructionID = instructionID; insn->spec = spec; return 0; } specWithOpsize = specifierForUID(instructionIDWithOpsize); if (is16BitEquvalent(spec->name, specWithOpsize->name)) { insn->instructionID = instructionIDWithOpsize; insn->spec = specWithOpsize; } else { insn->instructionID = instructionID; insn->spec = spec; } return 0; } insn->instructionID = instructionID; insn->spec = specifierForUID(insn->instructionID); return 0; }