Ejemplo n.º 1
0
static
void
debug_getthreadinfo(struct gdbcontext *ctx, const char *threadid)
{
	unsigned cpunum;
	char buf[128], xbuf[256];
	size_t i;

	cpunum = getthreadid(threadid);
	if (cpunum >= cpu_numcpus()) {
		debug_send(ctx, "E00");
		return;
	}

	/*
	 * Send back string of whatever info we want. Since gdb
	 * already fetches and prints the frame info, and fetches this
	 * but doesn't seem to print it, I dunno what to send.
	 */

	snprintf(buf, sizeof(buf), "CPU %u", cpunum);

	/* Code as hex for transmission */
	xbuf[0] = 0;
	for (i=0; buf[i]; i++) {
		printbyte(xbuf, sizeof(xbuf), (unsigned char)buf[i]);
	}
	debug_send(ctx, xbuf);
}
Ejemplo n.º 2
0
static
void
debug_read_mem(struct gdbcontext *ctx, const char *spec)
{
	uint32_t vaddr, length, i;
	uint32_t word;
	uint8_t byte;
	const char *curptr;
	char buf[BUFLEN];

	vaddr = strtoul(spec, (char **)&curptr, 16);
	length = strtoul(curptr+1, NULL, 16);

	buf[0] = 0;

	for (i=0; i<length && (vaddr+i)%4 != 0; i++) {
		if (cpudebug_fetch_byte(debug_cpu, vaddr+i, &byte)) {
			debug_send(ctx, "E03");
			return;
		}
		printbyte(buf, sizeof(buf), byte);
	}
	for (; i<length; i += 4) {
		if (cpudebug_fetch_word(debug_cpu, vaddr+i, &word)) {
			debug_send(ctx, "E03");
			return;
		}
		printword(buf, sizeof(buf), word);
	}
	debug_send(ctx, buf);
}
Ejemplo n.º 3
0
int symmetric_encrypt(char* buffer, char* ciphertext,int size)
{

 	int nc; /* amount of bytes [de]crypted at each step */
  	int nctot; /* total amount of encrypted bytes */
  	int pt_len; /* plain text size */
  	int ct_len; /* encrypted text size */
  	int ct_ptr; /* first available entry in the buffer */
  	int msg_len; /* message length */
	int k_size,i;
	char* key;
	FILE* fp;

	k_size=EVP_CIPHER_key_length(EVP_des_ecb());

 	key=malloc(k_size*sizeof(char)); /* encryption key */

 	/* Context allocation */
  	EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)malloc(sizeof(EVP_CIPHER_CTX));

  	/* Context initialization */
  	EVP_CIPHER_CTX_init(ctx);

 	/* Context setup for encryption */
  	EVP_EncryptInit(ctx, EVP_des_ecb(), NULL, NULL);

 	/* key generation */ 
	fp=fopen("key", "r");

	fread(key, 1,k_size, fp);

	fclose(fp);

	printf("\n symmetric key used is : \n");

	for (i = 0; i < k_size; i++)
    		printbyte(key[i]);
  	//printf("\n");

	/* Encryption key setup */
  	EVP_EncryptInit(ctx, NULL, key, NULL);

 	/* Encryption */
  	nc = 0;
  	nctot = 0;
  	ct_ptr = 0;

  	EVP_EncryptUpdate(ctx, ciphertext, &nc, buffer, size);
  
  	ct_ptr += nc;
  	nctot += nc;
  	
  	EVP_EncryptFinal(ctx, &ciphertext[ct_ptr], &nc);

  	nctot += nc; // total length of message

  	EVP_CIPHER_CTX_cleanup(ctx);

  	free(ctx);
	free(key);

  	//for (i = 0; i < nctot; i++) printbyte(ciphertext[i]);

  	printf("\n\n");
	return nctot;
	
}
Ejemplo n.º 4
0
   int send_file(char* file_name, int sk) {
	  
	FILE* file;

	FILE* fp;

	int name_size;			// size of the name of the file to be sent
	int size,k_size; 			// size of the file to be sent
	int ret, i; 			
	unsigned char* buffer;		// pointer to the buffer containing the file
	char* sym_key;

	int enckeysize;

	int remote_random,local_random;

char* password;

	//***** recieve the random value from server *****//

	ret = recv(sk, &remote_random, sizeof(int), MSG_WAITALL);


	file = fopen("key","r");

	/* Retrieve the size of the key to be sent */
	fseek(file,0,SEEK_END);
	k_size = ftell(file);

	/* Memory allocation for the key to be sent */
	sym_key = malloc(k_size * sizeof (char));
	fseek(file, 0, SEEK_SET);

	/* Read key from file */
	ret = fread(sym_key, 1, k_size, file);

	
//***** RSA ENCRYPTION PART BEGIN *****//

	char* enckey;

	RSA* rsa = RSA_new();

	fp = fopen("pub.pem","r");

	PEM_read_RSAPublicKey(fp,&rsa,NULL,NULL);

	enckeysize =RSA_size(rsa); 

	enckey=malloc(enckeysize * sizeof(char));

	RSA_encrypt(sym_key,enckey,k_size,rsa);

	fclose(fp);

//*** RSA ENCRYPTION PART end ***//
	
	/* Computation of the length of the filename */
	name_size = strlen(file_name);

	/* Open the file to be sent */
	file = fopen(file_name,"r");
	if(file == NULL) {
	  printf("\nError opening the file file\n");
	  return 1;
	}
    	
    	/* Retrieve the size of the file to be sent */
	fseek(file,0,SEEK_END);
	size = ftell(file);
	
	/* Memory allocation for the file to be sent */
	buffer = malloc(size * sizeof (char));
	fseek(file, 0, SEEK_SET);

	/* File reading */
	ret = fread(buffer, 1, size, file);
	  if(ret < size) {
	  printf("\n Error reading the file \n");
	  return 1;
	}
	
	fclose(file);
	
	/* The length of the file name is sent */
	ret = send(sk, &name_size, sizeof(name_size), 0);
 
	if(ret != sizeof(name_size)){
	  printf("\n Error trasmitting the length of the file name\n ");
	  return 1;
	}
    
	/* The file name is sent */
	ret = send(sk, file_name, name_size, 0); 
	if(ret < name_size){
	  printf("\n Error transmitting the file name\n ");
	  return 1;
	}
		


//****** Generate hash for freshness and origin(password) check *****//

	time_t t;
	int password_size;
	int fresh_size;
	char* fresh_txt;

	t = time(NULL);

 	srand ( time(NULL));

	local_random = rand();

	file = fopen("passofA.txt","r");

	fseek(file,0,SEEK_END);

	password_size = ftell(file);

	password = malloc(password_size * sizeof (char));

	fseek(file, 0, SEEK_SET);

	ret = fread(password, 1, password_size, file);
	
	fclose(file);

	int pass_hash_len;

	const EVP_MD *md1;

	md1 = EVP_get_digestbyname("sha1");

	unsigned char pass_md_value[EVP_MD_size(md1)];

	pass_hash_len=hash_gen(password,&pass_md_value[0]);

	fresh_size=sizeof(password)+sizeof(local_random)+sizeof(remote_random);
	
	fresh_txt = malloc(fresh_size);

	int loc_rand_size=sizeof(local_random);

	int rem_rand_size = sizeof(remote_random);

	memcpy(fresh_txt,&pass_md_value[0],pass_hash_len);

	memcpy(&fresh_txt[pass_hash_len],&local_random,loc_rand_size);

	memcpy(&fresh_txt[pass_hash_len+loc_rand_size],&remote_random,rem_rand_size);

	const EVP_MD *md;

	md = EVP_get_digestbyname("sha1");

	unsigned char md_value[EVP_MD_size(md)];
	
	int md_len;

	md_len=hash_gen(fresh_txt,&md_value[0]);

	printf("\n Freshness Digest is: \n");
        for(i = 0; i < md_len; i++) printbyte(md_value[i]);
        printf("\n");



///*** SYMMETRIC KEY ENCRYPTION PART BEGIN ***///

	char* totbuffer;
	int  nctot;
	char *plaintext, *ciphertext;
	int totbufsize = size+md_len;

	totbuffer = malloc(totbufsize);

	// message + digest for freshness and password 
	memcpy(totbuffer,buffer,size);  

	memcpy(&totbuffer[size],md_value,md_len);

	ciphertext = malloc(totbufsize+128);

	nctot = symmetric_encrypt(totbuffer,ciphertext,totbufsize); //  encrypted size


//***** SYMMETRIC KEY encryption part END *****///



//***** concatenate enckey and ciphertext *****//

	char* textnkeynhash;
	int totsize;

	totsize=nctot+enckeysize+loc_rand_size;
	
	textnkeynhash=malloc(totsize);
	
	memcpy(textnkeynhash,ciphertext,nctot);

	memcpy(&textnkeynhash[nctot],enckey,enckeysize);

	memcpy(&textnkeynhash[nctot+enckeysize],&local_random,loc_rand_size);


	/* The file size is sent */
	ret = send(sk, &totsize, sizeof(totsize), 0);
	  if(ret != sizeof(size)){
	  printf("\n Error transmitting the file size\n ");
	  return 1;
	}

	/* The file is sent */
	ret = send(sk, textnkeynhash, totsize, 0);
	if(ret < size){
	  printf("\n Error transmitting the file\n");
	  return 1;
	}
	
	printf("\n File %s with size %d bytes has been sent\n", file_name, totsize);
	free(buffer);
	free(ciphertext);
    
	return 0;
	
}
Ejemplo n.º 5
0
int receive_file(int sk) {

	int ret;
    	int name_size;		// length of the name of the received file
    	char* filename;		// name of the received file
    	int size,i;			// size of the buffer for the plaintext
    	char* buffer;		// plaintext buffer

    	FILE* file;			// pointer to the file where the received message will be saved

	time_t t;

	t = time(NULL);

 	srand ( time(NULL));

	int local_random = rand();

	send(sk, &local_random, sizeof(int), 0);

	printf("\n generated random value is %d",local_random);


    	/* Reception of the length of the file name */
    	ret = recv(sk, &name_size, sizeof(name_size), MSG_WAITALL);
	
    	if (ret != sizeof(name_size)) {
	  printf("%d \n Error receiving the length of the file name\n",ret);
	  return 1;
   	 }

   	 /* Memory allocation */
   	 filename = malloc(sizeof(char) * (name_size + 1));
   	 if(filename == NULL) {
      		printf("\n Error allocating memory\n");
      		return 1;
    	}

    	/* Reception of the file name */
    	ret = recv(sk, filename, name_size, MSG_WAITALL);
    
   	 if(ret != name_size){
     		 printf(" \n Error receiving the file name\n");
     		 return 1;
    	}
    
    filename[name_size] ='\0'; /* End of string */
 
    	/* Reception of the file size */
    	ret = recv(sk, &size, sizeof(size), MSG_WAITALL);
    	if(ret != sizeof(size)) {
      	printf("\n Error receiving the file size\n");
      	return 1;
    	}
 
   	 /* Memory allocation */
   	 buffer = malloc(size * sizeof(char));
    	if(buffer == NULL){
      		printf("\n Error allocating memory\n");
      		return 1;
    	}

    	/* Reception of the file */
    	ret = recv(sk, buffer, size, MSG_WAITALL);
    	if(ret != size) {
      		printf("\n Error receiving the file\n");
      		return 1;
    		}





//***** SEPARATE THE RECIEVED TEXT BEGIN *****//

	int remote_random;
	int md_len = 20;
	int rem_rand_size = sizeof(remote_random);
	char* recieved_hash;
	char* ciphertext;
	char* enc_key;
	int enckeysize =128; 
	int enctextsize;

	recieved_hash = malloc(md_len);

	RSA* rsa = RSA_new();
	
	enctextsize = size - enckeysize - rem_rand_size;
	
	ciphertext = malloc(enctextsize);

	enc_key = malloc(enckeysize);

 	memcpy(ciphertext,buffer,enctextsize);

	memcpy(enc_key,&buffer[enctextsize],enckeysize);

	memcpy(&remote_random,&buffer[enctextsize+enckeysize],rem_rand_size);
	

//****** Generate hash for freshness and origin(password) check *****//

	char* password;
	int password_size;
	int loc_rand_size;
	int fresh_size;
	char* fresh_txt;

	file = fopen("passofAhash.txt","r");

	fseek(file,0,SEEK_END);

	password_size = ftell(file);

	password = malloc(password_size * sizeof (char));

	fseek(file, 0, SEEK_SET);
	/* File reading */
	ret = fread(&password[0], 1, password_size, file);

	fclose(file);


	loc_rand_size=sizeof(local_random);

	fresh_size=password_size+loc_rand_size+sizeof(remote_random);
	
	fresh_txt = malloc(fresh_size);
	
	memcpy(fresh_txt,&password[0],password_size);

	memcpy(&fresh_txt[password_size],&local_random,loc_rand_size);

	memcpy(&fresh_txt[password_size+loc_rand_size],&remote_random,rem_rand_size);

	const EVP_MD *md;

	md = EVP_get_digestbyname("sha1");

	unsigned char md_value[EVP_MD_size(md)];

	md_len=hash_gen(fresh_txt,&md_value[0]);

	printf("\n \n Freshness hash calculated in server is:\n ");
        for(i = 0; i < md_len; i++) printbyte(md_value[i]);
        printf("\n");


//***** DECRYPT THE KEY PART BEGIN *****//

	char* key;
	int flen;
	FILE* fp;

	fp = fopen("priv.pem","r"); 
	
	OpenSSL_add_all_algorithms();

	rsa = PEM_read_RSAPrivateKey(fp,&rsa,NULL,"password");

	if(rsa == NULL) printf("\n ERROR reading rsa private key \n");

	flen = RSA_size(rsa);

	key = malloc(flen);

	ret = RSA_private_decrypt(flen,enc_key,key,rsa,RSA_PKCS1_PADDING);
	
	printf("\n Recieved symmetric key is : \n");
	for (i = 0; i < 8; i++)
    		printbyte(key[i]);
  	printf("\n");

	free(enc_key);
	fclose(fp);
	RSA_free(rsa);

///*** DECRYPT the key part END ***///

	

///*** DECRYPT THE MESSAGE PART BEGIN ***///

	int nctot;
	char* decryptedtext;
	char* plaintext;
	int msg_len;

	decryptedtext = (char *)malloc(enctextsize+128);

	//call decryption function
	nctot = symmetric_decrypt(ciphertext,decryptedtext,key, enctextsize);

	msg_len = nctot - md_len; //size of plaintext message

	plaintext = malloc(msg_len);

	//separate the plain text from the freshness and password hash
	memcpy(plaintext,decryptedtext,msg_len);

	memcpy(recieved_hash,&decryptedtext[msg_len],md_len);

	printf("\n \n Freshness hash recieved from client is: \n");
        for(i = 0; i < md_len; i++) printbyte(recieved_hash[i]);
        printf("\n");

	//compare recieved digest with locally calculated digest to 	check freshness and password
	ret = strcmp(recieved_hash,&md_value[0]);

	if(ret==0)printf("\n MESSAGE FRESHNESS AND ORIGIN IS VERIFIED"); 

	else printf("message not fresh with ret value %d",ret);


//***** DECRYPT the message part END *****//

	
    /* Open the file to save the received message */
    file = fopen(filename,"w");
      if(file == NULL) {
	printf("\n File not found\n");
	return 1;
    }
    
    /* Write the received message in the local file */
    ret = fwrite(plaintext, 1, msg_len, file);
    if(ret < msg_len) {
	printf("\n Error writing the file \n");
	return 1;
    }    
    
    printf("\n Received file %s with size %d bytes\n", filename, size);
    
    fclose(file);
    free(filename);
    free(buffer);
	free(ciphertext);
	free(plaintext);
	
    return 0;
   
}
Ejemplo n.º 6
0
int scdir( )
{
	SC_READER_INFO *ri;
	SC_CARD_INFO *ci;

	FieldPtr fld;
	FormPtr frm;

	int scerr=0;

	BYTE sprintb[80];
	BYTE buffer[255];
	int resplen;
	int ret;
	int i;
	LONG l;
	BOOLEAN bool1;
	WORD w1, w2;

	if( scInit() ) return(SCDIR_LIB_ERROR);

    ri = scGeneralNewReader( readerType, 1 );
	if( ri==NULL ) {
		scEnd();
		return(SCDIR_LIB_ERROR);
	}

    ci = scGeneralNewCard( );
	if( ci==NULL ) {
		scGeneralFreeReader( &ri );
		scEnd();
		return(SCDIR_LIB_ERROR);
	};

	/* Init Reader */
	ret = scReaderInit( ri, "1" );
	if( ret!=SC_EXIT_OK ) { scerr=SCDIR_READER_ERROR; goto exit; }

	/* Get Card Status */
	ret = scReaderCardStatus( ri );
	if( ret!=SC_EXIT_OK ) { scerr=SCDIR_READER_ERROR; goto exit; }
	if( !(ri->status&SC_CARD_STATUS_PRESENT) )
	{ scerr=SCDIR_NO_CARD; goto exit; }

	/* Activate Card */
	ret = scReaderActivate( ri );
	if(ret!=SC_EXIT_OK) { scerr=SCDIR_READER_ERROR; goto exit; }

	/* Reset Card */
	ret= scReaderResetCard( ri, ci );
	if(ret!=SC_EXIT_OK) { scerr=SCDIR_CARD_ERROR; goto exit; }

	/* Get Card Type */
	ci->type=0;
	ret = scSmartcardGetCardType( ci );
	if( (ret!=SC_EXIT_OK) && (ret!=SC_EXIT_NOT_SUPPORTED) )
	{ scerr=SCDIR_CARD_ERROR; goto exit; }

	frm = FrmGetActiveForm();
	fld = FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, dataFieldID)); 

	CleanField( fld );

	switch( ci->type )
	{
		case SC_CARD_MULTIFLEX_3K:
			myprintf0( "Card: Schlumberger Multiflex 3K\n" );
			break;
		case SC_CARD_MULTIFLEX_8K:
			myprintf0( "Card: Schlumberger Multiflex 8K\n" );
			break;
		case SC_CARD_MULTIFLEX_8K_DES:
			myprintf0( "Card: Schlumberger Multiflex 8K (with Full DES option)\n" );
			break;
		case SC_CARD_CRYPTOFLEX:
			myprintf0( "Card: Schlumberger Cryptoflex\n" );
			break;
		case SC_CARD_CRYPTOFLEX_DES:
			myprintf0( "Card: Schlumberger Cryptoflex (with Full DES option)\n" );
			break;
		case SC_CARD_CRYPTOFLEX_KEYGEN:
			myprintf0( "Card: Schlumberger Cryptoflex (with RSA key generation)\n" );
			break;
		case SC_CARD_CYBERFLEX:
			myprintf0( "Card: Schlumberger Cyberflex\n" );
			break;
		case SC_CARD_PAYFLEX_1K_USER:
			myprintf0( "Card: Schlumberger Payflex 1K User card\n" );
			break;
		case SC_CARD_PAYFLEX_1K_SAM:
			myprintf0( "Card: Schlumberger Payflex 1K SAM\n" );
			break;
		case SC_CARD_PAYFLEX_4K_USER:
			myprintf0( "Card: Schlumberger Payflex 4K User card\n" );
			break;
		case SC_CARD_PAYFLEX_4K_SAM:
			myprintf0( "Card: Schlumberger Payflex 4K SAM\n" );
			break;
		case SC_CARD_GPK4000_S:
			myprintf0( "Card: Gemplus GPK4000-s\n" );
			break;
		case SC_CARD_GPK4000_SP:
			myprintf0( "Card: Gemplus GPK4000-sp\n" );
			break;
		case SC_CARD_GPK4000_SDO:
			myprintf0( "Card: Gemplus GPK4000-sdo\n" );
			break;
		case SC_CARD_GPK2000_S:
			myprintf0( "Card: Gemplus GPK2000-s\n" );
			break;
		case SC_CARD_GPK2000_SP:
			myprintf0( "Card: Gemplus GPK2000-sp\n" );
			break;
		case SC_CARD_MPCOS_EMV_1B:
			myprintf0( "Card: Gemplus EMV (1-Byte data units)\n" );
			break;
		case SC_CARD_MPCOS_EMV_4B:
			myprintf0( "Card: Gemplus EMV (4-Byte data units)\n" );
			break;
		case SC_CARD_GELDKARTE:
			myprintf0( "Card: Geldkarte\n" );
			break;
		case SC_CARD_TCOS:
			myprintf0("Telesec TCOS 2 card\n");
			break;
		case SC_CARD_TCOS_44:
			myprintf0("Telesec TCOS 2 card (SLE44)\n");
			break;
		case SC_CARD_TCOS_66:
			myprintf0("Telesec TCOS 2 card (SLE66)\n");
			break;
		case SC_CARD_BASICCARD:
			myprintf0( "Card: BasicCard\n" );
			break;
		case SC_CARD_BASICCARD_COMP:
			myprintf0( "Card: Compact BasicCard\n" );
			break;
		case SC_CARD_BASICCARD_ENH:
			myprintf0( "Card: Enhanced BasicCard\n" );
			break;
		case SC_CARD_BRADESCO:
			myprintf0( "Card: Moeda Eletronica Bradesco\n" );
			break;
		case SC_CARD_GSMSIM:
			myprintf0( "Card: GSM SIM card.\n" );
			break;
		case SC_CARD_UNKNOWN:
		default:
			myprintf0( "Card: Unknown\n" );
	}

	FldDrawField(fld);

	printarray( fld, "ATR:", ci->atrlen, ci->atr );

	switch( ci->type )
	{
#ifdef WITH_MULTIFLEX
		case SC_CARD_MULTIFLEX_3K:
		case SC_CARD_MULTIFLEX_8K:
		case SC_CARD_MULTIFLEX_8K_DES:
			/* Select EF */
			ret = scMultiflexCmdSelectFile( ri, ci, 0x0002, buffer,
				&resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			/* Read */
			resplen=8;
			ret = scMultiflexCmdReadBinary( ri, ci, 0, buffer,
				&resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Serial number:", resplen, buffer );

			/* Select MF */
			ret = scMultiflexCmdSelectFile( ri, ci, 0x3F00, buffer,
				&resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			myprintf0("Master File (3F00):\n");

			i=(buffer[2]<<8)+buffer[3];
			myprintf1("  Free: %d Bytes\n",i);

			i=buffer[14];
			myprintf1("  Number of DFs: %d\n",i);

			i=buffer[15];
			myprintf1("  Number of EFs: %d\n",i);

			i=buffer[16];
			myprintf1("  Number of secret codes: %d\n",i);

			i=buffer[18];
			myprintf1("  CHV status: %d\n",i);

			i=buffer[19];
			myprintf1("  CHV unblocking key status: %d\n",i);

			FldDrawField(fld);

			break;
#endif /* WITH_MULTIFLEX */
#ifdef WITH_CRYPTOFLEX
		case SC_CARD_CRYPTOFLEX:
		case SC_CARD_CRYPTOFLEX_DES:
		case SC_CARD_CRYPTOFLEX_KEYGEN:
			/* Select EF */
			ret = scCryptoflexCmdSelectFile( ri, ci, 0x0002, buffer,
				&resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			/* Read */
			resplen=8;
			ret = scCryptoflexCmdReadBinary( ri, ci, 0, buffer,
				&resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Serial number:", resplen, buffer );

			/* Select MF */
			ret = scCryptoflexCmdSelectFile( ri, ci, 0x3F00, buffer,
				&resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			myprintf0("Master File (3F00):\n");

			i=(buffer[2]<<8)+buffer[3];
			myprintf1("  Free: %d Bytes\n",i);

			i=buffer[14];
			myprintf1("  Number of DFs: %d\n",i);

			i=buffer[15];
			myprintf1("  Number of EFs: %d\n",i);

			i=buffer[16];
			myprintf1("  Number of secret codes: %d\n",i);

			i=buffer[18];
			myprintf1("  CHV status: %d\n",i);

			i=buffer[19];
			myprintf1("  CHV unblocking key status: %d\n",i);

			FldDrawField(fld);

			break;
#endif /* WITH_CRYPTOFLEX */
#ifdef WITH_GPK4000
		case SC_CARD_GPK4000_S:
		case SC_CARD_GPK4000_SP:
		case SC_CARD_GPK4000_SDO:
			/* Chip Serial Number */
			ret = scGpk4000CmdGetInfo( ri, ci,
				SC_GPK4000_INFO_CHIP_SN, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Chip serial number:", resplen, buffer );

			/* Card Serial Number */
			ret = scGpk4000CmdGetInfo( ri, ci,
				SC_GPK4000_INFO_CARD_SN, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Card serial number:", resplen, buffer );

			/* Issuer Serial Number */
			ret = scGpk4000CmdGetInfo( ri, ci,
				SC_GPK4000_INFO_ISSUER_SN, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Issuer serial number:", resplen, buffer );

			/* Issuer Reference Number */
			ret = scGpk4000CmdGetInfo( ri, ci,
				SC_GPK4000_INFO_ISSUER_REF, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Issuer reference number:", resplen, buffer );

			/* Pre-issuing data */
			ret = scGpk4000CmdGetInfo( ri, ci,
				SC_GPK4000_INFO_PRE_ISSUING, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Pre-issuing data:", resplen, buffer );

			break;
#endif /* WITH_GPK4000 */
#ifdef WITH_BASICCARD
		case SC_CARD_BASICCARD:
		case SC_CARD_BASICCARD_COMP:
		case SC_CARD_BASICCARD_ENH:
			/* State */
			ret = scBasiccardCmdGetState( ri, ci, buffer, &bool1 );
			testretsws(SCDIR_CARD_ERROR);

			switch( buffer[0] ) {
				case 0:
					myprintf0( "State: NEW\n" );
					break;
				case 1:
					myprintf0( "State: LOAD\n" );
					break;
				case 2:
					myprintf0( "State: TEST\n" );
					break;
				case 3:
					myprintf0( "State: RUN\n" );
					break;
				default:
					myprintf0(" State: Unknown\n" );
			}

			FldDrawField(fld);

			if( (buffer[0]==SC_BASICCARD_STATE_NEW) ||
				(buffer[0]==SC_BASICCARD_STATE_LOAD) ) {
				/* EEPROM Size */
				ret = scBasiccardCmdEepromSize( ri, ci, &w1, &w2 );
				testretsws(SCDIR_CARD_ERROR);

				myprintf0( "EEPROM:\n" );
				myprintf1( "  Start address: %lxh\n", (long)w1 );
				myprintf1( "  Size:          %d\n", w2 );
			}

			FldDrawField(fld);

			if( (buffer[0]==SC_BASICCARD_STATE_TEST) ||
				(buffer[0]==SC_BASICCARD_STATE_RUN) ) {
				/* Application ID */
				ret = scBasiccardCmdGetApplId( ri, ci, buffer, &resplen );
				testretsws(SCDIR_CARD_ERROR);

				printarray( fld, "Application ID:", resplen, buffer );
			}

			break;
#endif /* WITH_BASICCARD */
#ifdef WITH_TCOS
		case SC_CARD_TCOS:
		case SC_CARD_TCOS_44:
		case SC_CARD_TCOS_66:
			/* Select EF(GDO) */
			ret = scTcosCmdSelect( ri, ci, SC_TCOS_SELECT_ABS_PATH, 0,
				"\x2F\x02", 2, SC_TCOS_RDATA_FCI, buffer, &resplen );
			testreturn(SCDIR_CARD_ERROR);
			if( ci->sw[0]==0x90 ) {
				/* Read */
				resplen=0;
				ret = scTcosCmdReadBinary( ri, ci, 0, buffer, &resplen );
				testretsw(SCDIR_CARD_ERROR,0x90,0x00);

				/* Should interpret the BER structure. */
				printarray( fld, "Serial number:", buffer[1], (buffer+2) );
			}

			/* Select EF(DIR) */
			ret = scTcosCmdSelect( ri, ci, SC_TCOS_SELECT_ABS_PATH, 0,
				"\x2F\x00", 2, SC_TCOS_RDATA_FCI, buffer, &resplen );
			testreturn(SCDIR_CARD_ERROR);
			if( ci->sw[0]==0x90 ) {
				/* Read */
				resplen=0;
				ret = scTcosCmdReadBinary( ri, ci, 0, buffer, &resplen );
				testretsw(SCDIR_CARD_ERROR,0x90,0x00);

				/* Should interpret the BER structure. */
				printarray( fld, "AID:", buffer[1], (buffer+2) );
			}

			break;
#endif /* WITH_TCOS */
#ifdef WITH_GPK4000
		case SC_CARD_BRADESCO:
			/* Card Serial Number */
			ret = scGpk4000CmdGetInfo( ri, ci,
				SC_GPK4000_INFO_CARD_SN, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Card serial number:", resplen, buffer );

			/* Issuer Serial Number */
			ret = scGpk4000CmdGetInfo( ri, ci,
				SC_GPK4000_INFO_ISSUER_SN, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Issuer serial number:", resplen, buffer );

			/* Issuer Reference Number */
			ret = scGpk4000CmdGetInfo( ri, ci,
				SC_GPK4000_INFO_ISSUER_REF, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray( fld, "Issuer reference number:", resplen, buffer );

			/* Select DF */
			ret = scGpk4000CmdSelFil( ri, ci, SC_GPK4000_SELECT_DF,
				0x0200, NULL, 0, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			/* Read Binary */
			resplen = 6;
			ret = scGpk4000CmdRdBin( ri, ci, 0x8100, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			myprintf1("Account: %hd/", (buffer[0]<<8)+buffer[1] );
			myprintf1("%ld\n",
				((long)buffer[2]<<24)+((long)buffer[3]<<16)+((long)buffer[4]<<8)+buffer[5]);

			FldDrawField(fld);

			/* Read Binary */
			resplen = 3;
			ret = scGpk4000CmdRdBin( ri, ci, 0x8202, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			l=((long)buffer[0]<<16)+((long)buffer[1]<<8)+buffer[2];
			myprintf1("Balance: R$ %ld.", (long) l/100 );
			myprintf1("%hd", (short) (l/10)%10 );
			myprintf1("%hd\n", (short) l%10 );

			FldDrawField(fld);

			break;
#endif /* WITH_GPK4000 */
		default:
			break;
	}
#ifdef WITH_GELDKARTE
	if( ci->type==SC_CARD_GELDKARTE ) {
			/* EF_ID */
			/* Select MF */
			ret = scGeldkarteCmdSelectFile( ri, ci, 
				SC_GELDKARTE_SELECT_MF, 0, NULL, 0,
				SC_GELDKARTE_SELRESP_NONE, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);
			/* Select EF */
			ret = scGeldkarteCmdSelectFile( ri, ci, 
				SC_GELDKARTE_SELECT_EF, 0x0003, NULL, 0,
				SC_GELDKARTE_SELRESP_NONE, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);
			/* Read Record */
			resplen = 22;
			ret = scGeldkarteCmdReadRecord( ri, ci, 1,
				SC_GELDKARTE_READREC_SELECTED, 0, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			printarray2(fld,"Karteninstitut: ", 3, (buffer+1) );
			printarray2(fld,"Kartennummer: ", 5, (buffer+4) );
			myprintf0("Aktivierungsdatum: ");
			printbyte(buffer[14]);
			myprintf0("/");
			printbyte(buffer[13]);
			myprintf0("/");
			printbyte(buffer[12]);
			myprintf0("\nVerfallsdatum: ");
			printbyte(buffer[11]);
			myprintf0("/");
			printbyte(buffer[10]);
			myprintf0("\nLand: ");
			printbyte(buffer[15]);
			printbyte(buffer[16]);
			myprintf3("\nWaehrung: %c%c%c\n", buffer[17], buffer[18],
				buffer[19] );

			/* EF_VERSION */
			/* Select MF */
			ret = scGeldkarteCmdSelectFile( ri, ci, 
				SC_GELDKARTE_SELECT_MF, 0, NULL, 0,
				SC_GELDKARTE_SELRESP_NONE, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);
			/* Select EF */
			ret = scGeldkarteCmdSelectFile( ri, ci, 
				SC_GELDKARTE_SELECT_EF, 0x0017, NULL, 0,
				SC_GELDKARTE_SELRESP_NONE, buffer, &resplen );
			testreturn(SCDIR_CARD_ERROR);
			if( ci->sw[0]==0x90 ) {
				/* Read Record */
				resplen = 8;
				ret = scGeldkarteCmdReadRecord( ri, ci, 1,
					SC_GELDKARTE_READREC_SELECTED, 0, buffer, &resplen );
				testretsw(SCDIR_CARD_ERROR,0x90,0x00);
			
				printarray(fld,"Version:", 8, buffer );
			}

			/* Select Application */
			ret = scGeldkarteCmdSelectFile( ri, ci, 
				SC_GELDKARTE_SELECT_AID, 0,
				"\xD2\x76\x00\x00\x25\x45\x50\x01\x00", 9,
				SC_GELDKARTE_SELRESP_NONE, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			/* EF_BETRAG */
			/* Read Record */
			resplen = 9;
			ret = scGeldkarteCmdReadRecord( ri, ci, 1,
				SC_GELDKARTE_READREC_SFID, 0x18, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			myprintf0("Betrag: ");
			printbyte(buffer[0]);
			printbyte(buffer[1]);
			myprintf0(".");
			printbyte(buffer[2]);
			myprintf0("\nMax. Betrag: ");
			printbyte(buffer[3]);
			printbyte(buffer[4]);
			myprintf0(".");
			printbyte(buffer[5]);
			myprintf0("\nMax. Transaktion: ");
			printbyte(buffer[6]);
			printbyte(buffer[7]);
			myprintf0(".");
			printbyte(buffer[8]);
			myprintf0("\n");

			/* EF_BOeRSE */
			/* Read Record */
			resplen = 27;
			ret = scGeldkarteCmdReadRecord( ri, ci, 1,
				SC_GELDKARTE_READREC_SFID, 0x19, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			switch( buffer[0] ) {
				case 0x00:
					myprintf0("Kartentyp: Geldkarte\n");
					break;
				case 0xFF:
					myprintf0("Kartentyp: Wertkarte\n");
					break;
				default:
					myprintf0("Kartentyp: unknown\n");
					break;
			}
			myprintf0("Boersenverrechnungskonto:\n");
			printarray2(fld,"  BLZ:         ", 4, (buffer+1) );
			printarray2(fld,"  Kontonummer: ", 5, (buffer+5) );

			/* EF_LSEQ */
			/* Read Record */
			resplen = 2;
			ret = scGeldkarteCmdReadRecord( ri, ci, 1,
				SC_GELDKARTE_READREC_SFID, 0x1A, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			w1=((WORD)buffer[0]<<8)+buffer[1]-1;
			myprintf1("Ladevorgaenge: %hd\n", w1 );

			/* EF_LBEQ */
			/* Read Record */
			resplen = 2;
			ret = scGeldkarteCmdReadRecord( ri, ci, 1,
				SC_GELDKARTE_READREC_SFID, 0x1B, buffer, &resplen );
			testretsw(SCDIR_CARD_ERROR,0x90,0x00);

			w1=((WORD)buffer[0]<<8)+buffer[1]-1;
			myprintf1("Abbuchungen: %hd\n", w1 );

			/* EF_LLOG */
			myprintf0("Lade-/Entladevorgaenge:\n");
			for( i=1; i<4; i++ ) {
				/* Read Record */
				resplen = 33;
				ret = scGeldkarteCmdReadRecord( ri, ci, (BYTE)i,
					SC_GELDKARTE_READREC_SFID, 0x1C, buffer, &resplen );
				if( (ret!=SC_EXIT_OK) || (ci->sw[0]!=0x90) )
					break;

				if( buffer[0]==0x00 ) { break; }

				myprintf1("%d)\n", i );

				myprintf0("  Vorgang: ");
				switch( buffer[0] ) {
					case 0x01:
					case 0x03:
						myprintf0("Laden einleiten\n");
						break;
					case 0x05:
					case 0x07:
						myprintf0("Laden einleiten wiederholen\n");
						break;
					case 0x10:
					case 0x11:
					case 0x12:
					case 0x13:
					case 0x14:
					case 0x15:
					case 0x16:
					case 0x17:
						myprintf0("Laden\n");
						break;
					case 0x21:
						myprintf0("Entladen einleiten\n");
						break;
					case 0x25:
						myprintf0("Endladen einleiten wiederholen\n");
						break;
					case 0x30:
					case 0x31:
					case 0x34:
					case 0x35:
						myprintf0("Entladen\n");
						break;
					default:
						myprintf0("Unbekannt\n");
						break;
				}

				w1=((WORD)buffer[1]<<8)+buffer[2];
				myprintf1("  Ladevorgang: %hd\n", w1 );

				w1=((WORD)buffer[31]<<8)+buffer[32];
				myprintf1("  Abbuchungen: %hd\n", w1 );

				myprintf0("  Betrag: ");
				printbyte(buffer[4]);
				printbyte(buffer[5]);
				myprintf0(".");
				printbyte(buffer[6]);

				printarray2(fld,"\n  Terminal-ID:", 8, (buffer+13) );

				printarray2(fld,"  Terminal-Sequenznummer:", 3, (buffer+21) );

				if( buffer[26]!=0x00 ) {
					myprintf0("  Datum: ");
					printbyte(buffer[27]);
					myprintf0("/");
					printbyte(buffer[26]);
					myprintf0("/");
					printbyte(buffer[24]);
					printbyte(buffer[25]);
					myprintf0("\n");
				}

				if( !( (buffer[28]==0x00) && (buffer[29]==0x00) &&
					(buffer[30]==0x00) ) )  {
					myprintf0("  Uhrzeit: ");
					printbyte(buffer[28]);
					myprintf0(":");
					printbyte(buffer[29]);
					myprintf0(":");
					printbyte(buffer[30]);
					myprintf0("\n");
				}
			}

			/* EF_BLOG */
			myprintf0("Ab-/Rueckbuchungen:\n");
			for( i=1; i<16; i++ ) {
				/* Read Record */
				resplen = 37;
				ret = scGeldkarteCmdReadRecord( ri, ci, (BYTE)i,
					SC_GELDKARTE_READREC_SFID, 0x1D, buffer, &resplen );
				if( (ret!=SC_EXIT_OK) || (ci->sw[0]!=0x90) )
					break;

				if( buffer[0]==0x00 ) { break; }

				myprintf1("%d)\n", i );

				myprintf0("  Vorgang: ");
				switch( buffer[0] ) {
					case 0x50:
					case 0x51:
						myprintf0("Abbuchen\n");
						break;
					case 0x70:
					case 0x71:
						myprintf0("Rueckbuchen\n");
						break;
					default:
						myprintf0("Unbekannt\n");
						break;
				}

				w1=((WORD)buffer[1]<<8)+buffer[2];
				myprintf1("  Abbuchung: %hd\n", w1 );

				w1=((WORD)buffer[3]<<8)+buffer[4];
				myprintf1("  Ladevorgaenge: %hd\n", w1 );

				myprintf0("  Betrag: ");
				printbyte(buffer[5]);
				printbyte(buffer[6]);
				myprintf0(".");
				printbyte(buffer[7]);

				printarray2(fld,"\n  Haendlerkartennummer:", 10, (buffer+8) );

				myprintf1("  Haendlersequenznummer: %ld\n",
					((LONG)buffer[18]<<24)+((LONG)buffer[19]<<16)+
					((LONG)buffer[20]<<8)+buffer[21] );

				myprintf1("  Haendlersummensequenznummer: %ld\n",
					((LONG)buffer[22]<<24)+((LONG)buffer[23]<<16)+
					((LONG)buffer[24]<<8)+buffer[25] );

				if( buffer[31]!=0x00 ) {
					myprintf0("  Datum: ");
					printbyte(buffer[32]);
					myprintf0("/");
					printbyte(buffer[31]);
					myprintf0("/");
					printbyte(buffer[29]);
					printbyte(buffer[30]);
					myprintf0("\n");
				}

				if( !( (buffer[33]==0x00) && (buffer[34]==0x00) &&
					(buffer[35]==0x00) ) )  {
					myprintf0("  Uhrzeit: ");
					printbyte(buffer[33]);
					myprintf0(":");
					printbyte(buffer[34]);
					myprintf0(":");
					printbyte(buffer[35]);
					myprintf0("\n");
				}
			}

	}
#endif /* WITH_GELDKARTE */
#ifdef WITH_GSMSIM
	if( ci->type==SC_CARD_GSMSIM ) {
		/* ICCID */
		/* Select */
		ret = scGsmsimCmdSelect( ri, ci, 0x2FE2, buffer, &resplen );
		if( (ret==0) && (ci->sw[0]==0x90) && (ci->sw[1]==0x00) ) {
			/* Read Binary */
			resplen=10;
			ret = scGsmsimCmdReadBin( ri, ci, 0, buffer, &resplen );
			if( (ret==0) && (ci->sw[0]==0x90) && (ci->sw[1]==0x00) )
				printarray2( fld, "ICCID:", resplen, buffer );
		}
	}
#endif /* WITH_GSMSIM */

exit:
	scReaderDeactivate( ri );
	scReaderShutdown( ri );

	scGeneralFreeCard( &ci );
	scGeneralFreeReader( &ri );

	scEnd();

	return(scerr);
}
Ejemplo n.º 7
0
// Very simple printf.  Only for debugging prints.
// Do not add to this without checking with Rob.
static void
vprintf(int8 *s, byte *base)
{
	int8 *p, *lp;
	uintptr arg, narg;
	byte *v;

	//runtime·lock(&debuglock);

	lp = p = s;
	arg = 0;
	for(; *p; p++) {
		if(*p != '%')
			continue;
		if(p > lp)
			gwrite(lp, p-lp);
		p++;
		narg = 0;
		switch(*p) {
		case 't':
		case 'c':
			narg = arg + 1;
			break;
		case 'd':	// 32-bit
		case 'x':
			arg = ROUND(arg, 4);
			narg = arg + 4;
			break;
		case 'D':	// 64-bit
		case 'U':
		case 'X':
		case 'f':
			arg = ROUND(arg, sizeof(uintptr));
			narg = arg + 8;
			break;
		case 'C':
			arg = ROUND(arg, sizeof(uintptr));
			narg = arg + 16;
			break;
		case 'p':	// pointer-sized
		case 's':
			arg = ROUND(arg, sizeof(uintptr));
			narg = arg + sizeof(uintptr);
			break;
		case 'S':	// pointer-aligned but bigger
			arg = ROUND(arg, sizeof(uintptr));
			narg = arg + sizeof(String);
			break;
		case 'a':	// pointer-aligned but bigger
			arg = ROUND(arg, sizeof(uintptr));
			narg = arg + sizeof(Slice);
			break;
		case 'i':	// pointer-aligned but bigger
		case 'e':
			arg = ROUND(arg, sizeof(uintptr));
			narg = arg + sizeof(Eface);
			break;
		}
		v = base+arg;
		switch(*p) {
		case 'a':
			runtime·printslice(*(Slice*)v);
			break;
		case 'c':
			runtime·printbyte(*(int8*)v);
			break;
		case 'd':
			runtime·printint(*(int32*)v);
			break;
		case 'D':
			runtime·printint(*(int64*)v);
			break;
		case 'e':
			runtime·printeface(*(Eface*)v);
			break;
		case 'f':
			runtime·printfloat(*(float64*)v);
			break;
		case 'C':
			runtime·printcomplex(*(Complex128*)v);
			break;
		case 'i':
			runtime·printiface(*(Iface*)v);
			break;
		case 'p':
			runtime·printpointer(*(void**)v);
			break;
		case 's':
			runtime·prints(*(int8**)v);
			break;
		case 'S':
			runtime·printstring(*(String*)v);
			break;
		case 't':
			runtime·printbool(*(bool*)v);
			break;
		case 'U':
			runtime·printuint(*(uint64*)v);
			break;
		case 'x':
			runtime·printhex(*(uint32*)v);
			break;
		case 'X':
			runtime·printhex(*(uint64*)v);
			break;
		}
		arg = narg;
		lp = p+1;
	}
	if(p > lp)
		gwrite(lp, p-lp);

	//runtime·unlock(&debuglock);
}
Ejemplo n.º 8
0
int main(int argc, char **argv)
{
   ushort fromtable[256],desttable[256];
   int c,d,firstdiff;
   bool createutf;
   ushort uc;
       
   if(argc != 4 && argc!=5)
   {
      fprintf(stderr,"Usage: makechs <fromchrs> <destchrs> <frommap> [<destmap>]\n");
      exit(0);
   }
   
   if(argc == 4) createutf=TRUE;
   else          createutf=FALSE;
   
   if(!(readmap(fromtable,argv[3])))
      exit(0);

   if(!createutf)
   {      
      if(!(readmap(desttable,argv[4])))
         exit(0);
   }

   if(createutf)
   {
      firstdiff=0;
   }
   else
   {
      for(c=0;c<256;c++)
      {
         if(fromtable[c] != desttable[c])
         {
            firstdiff=c;
            break;
         }
       }
   }   
      
   printf(";\n");
   printf("; Generated by makechs 1.0 by Johan Billing. Some tweaking may be required.\n");
   printf(";\n");
      
   if(createutf || firstdiff < 128)
      printf("100000          ; ID number (when >65535, all 255 chars will be translated)\n");
      
   else
      printf("0               ; ID number (when >65535, all 255 chars will be translated)\n");
      
   printf("0               ; version number\n");
   printf(";\n");
   printf("2               ; level number\n");
   printf(";\n");
   printf("%s\n",argv[1]);
   printf("%s\n",argv[2]);
   printf(";\n");
   
   for(c=0;c<256;c++)
   {
      if(createutf)
      {
         uc=fromtable[c];
         
         if(uc < 0x80)
         {
            printbyte(0);
            printf("\t");
            printbyte(uc);
            printf("\n");
         }
         else if(uc < 0x800)
         {
            printbyte(0xC0 | (uc >> 6));
            printf("\t");
            printbyte(0x80 | (uc & 0x3F));
            printf("\n");
         }
         else
         {
            printbyte(0xE0 | (uc >> 12));
            printf("\t");
            printbyte(0x80 | ((uc >> 6) & 0x3F));
            printf("\t");
            printbyte(0x80 | (uc        & 0x3F));
            printf("\n");
         }     
      }
Ejemplo n.º 9
0
/* pkt is null-terminated */
void 
debug_exec(struct gdbcontext *ctx, const char *pkt) 
{
	char *cs;  /* start of the checksum */
	int i;
	int check = 0, scheck;

#ifdef SHOW_PACKETS
	msg("Got packet %s", pkt);
#endif

	if (pkt[0] != '$') {
		return;
	}

	cs = strchr(pkt, '#');
	if (cs == NULL) {
		return;
	}
	*cs = 0;
	cs++;

	for (i=1; pkt[i]; i++) {
		check += pkt[i];
	}

	scheck = strtoul(cs, NULL, 16);
	if (scheck != check % 256) {
		write(ctx->myfd, "-", 1);
		return;
	} else {
		write(ctx->myfd, "+", 1);
	}

	switch (pkt[1]) {
	    case '!':
		/*
		 * Enable extended mode -- extended mode is apparently
		 * where gdb can ask to rerun the program. We can't do
		 * that... although it could probably be arranged.
		 *
		 * Reply with "OK" if extended mode is enabled.
		 */
		debug_notsupp(ctx);
		break;
	    case '?':
		/* Report why the target stopped. */
		debug_send_stopinfo(ctx);
		break;
	    case 'A':
		/*
		 * Set argv[]. We can't do this, although it might make
		 * sense if we grow support for reloading the kernel.
		 */
		debug_notsupp(ctx);
		break;
	    case 'b':
		if (pkt[2] == 0) {
			/* Set serial bit rate; deprecated. */
			debug_notsupp(ctx);
			break;
		}
		else if (pkt[2] == 'c') {
			/* Backward continue - resume executing, backwards */
		}
		else if (pkt[2] == 's') {
			/* Backward single step - execute one insn backwards */
		}
		else {
			/* ? */
		}
		debug_notsupp(ctx);
		break;
	    case 'B':
		/* Set or clear breakpoint; old, deprecated. */
		debug_notsupp(ctx);
		break;
	    case 'c':
		/*
		 * Continue. If an address follows the 'c', continue
		 * from that address. debug_restart() does that.
		 */
		debug_restart(ctx, pkt + 2);
		unset_breakcond();
		break;
	    case 'C':
		/*
		 * Continue with signal. A signal number in hex
		 * follows the C; that may be followed with a
		 * semicolon and an address to continue at. We don't
		 * have signals per se; in theory we could fake up
		 * some mapping of signals to hardware traps, but that
		 * would be difficult to arrange and not serve much
		 * purpose.
		 */
		debug_notsupp(ctx);
		break;
	    case 'd':
		/* Toggle debug flag (whatever that means); deprecated. */
		debug_notsupp(ctx);
		break;
	    case 'D':
		/*
		 * Detach. With a process-id, detach only one process,
		 * if the multiprocess extension is in use.
		 */
		debug_send(ctx, "OK");
		unset_breakcond();
		break;
	    case 'F':
		/*
		 * File I/O extension reply; for now at least we have
		 * no use for this.
		 */
		debug_notsupp(ctx);
		break;
	    case 'g':
		/* Read general-purpose registers */
		debug_register_print(ctx);
		break;
	    case 'G':
		/*
		 * Write general-purpose registers. The G is followed
		 * by a register dump in the same format as the 'g'
		 * reply.
		 */
		// XXX gcc docs say this is required
		debug_notsupp(ctx);
		break;
	    case 'H':
		/*
		 * Hc followed by a thread ID sets the thread that
		 * step and continue operations should affect; Hg
		 * followed by a thread ID sets the thread that
		 * other operations should affect.
		 */
		if (pkt[2] == 'c') {
			debug_notsupp(ctx);
		}
		else if (pkt[2] == 'g') {
			unsigned cpunum;

			cpunum = getthreadid(pkt+3);
			if (cpunum >= cpu_numcpus()) {
				debug_send(ctx, "E00");
				break;
			}
			debug_cpu = cpunum;
			debug_send(ctx, "OK");
		}
		else {
			debug_send(ctx, "OK");
		}
		break;
	    case 'i':
		/* Step by cycle count */
		debug_notsupp(ctx);
		break;
	    case 'I':
		/* Step by cycle count with signal (apparently) */
		debug_notsupp(ctx);
		break;
	    case 'k':
		/* Kill the target */
		// don't do this - debugger hangs up and we get SIGPIPE
		//debug_send(ctx, "OK");
		msg("Debugger requested kill");
		reqdie();
		// To continue running instead of dying, do this instead
		//unset_breakcond();
		break;
	    case 'm':
		/* Read target memory */
		debug_read_mem(ctx, pkt + 2);
		break;
	    case 'M':
		/* Write target memory */
		debug_write_mem(ctx, pkt + 2);
		break;
	    case 'p':
		/* read one register */
		debug_notsupp(ctx);
		break;
	    case 'P':
		/* write one register */
		debug_notsupp(ctx);
		break;
	    case 'q':
		/* General query */
		if (strcmp(pkt + 2, "C") == 0) {
			/* Return current thread id */
			debug_sendf(ctx,"QC%x", mkthreadid(debug_cpu));
		}
		else if (!strcmp(pkt+2, "fThreadInfo")) {
			char buf[128];
			unsigned i;

			strcpy(buf, "m");
			for (i=0; i<cpu_numcpus(); i++) {
				if (!cpu_enabled(i)) {
					continue;
				}
				if (i > 0) {
					strcat(buf, ",");
				}
				printbyte(buf, sizeof(buf), mkthreadid(i));
			}
			debug_send(ctx, buf);
		}
		else if (!strcmp(pkt+2, "sThreadInfo")) {
			debug_send(ctx, "l");
		}
		else if (strcmp(pkt+2, "Offsets") == 0) {
			/* Return info about load-time relocations */ 
			debug_notsupp(ctx);
		}
		else if (strcmp(pkt+2, "Supported") == 0) {
			/* Features handshake */
			debug_notsupp(ctx);
		}
		else if (!strncmp(pkt+2, "ThreadExtraInfo,", 16)) {
			debug_getthreadinfo(ctx, pkt+2+16);
		}
		else {
			debug_notsupp(ctx);
		}
		break;
	    case 'Q':
		/* General set mode (I think) */
		debug_notsupp(ctx);
		break;
	    case 'r':
		/* Reset target - deprecated */
		debug_notsupp(ctx);
		break;
	    case 'R':
		/*
		 * Restart target (only with extended mode enabled).
		 * Do not reply.
		 */
		break;
	    case 's':
		/* Single step */
		debug_restart(ctx, pkt + 2);
		onecycle();
		debug_send_stopinfo(ctx);
		break;
	    case 'S':
		/* Single step with signal */
		debug_notsupp(ctx);
		break;
	    case 't':
		/* search memory for a pattern (underdocumented) */
		debug_notsupp(ctx);
		break;
	    case 'T':
		/* check if a thread is alive (OK - yes; E.. - no) */
		debug_checkthread(ctx, pkt + 2);
		break;
	    case 'v':
		/* various longer commands */
		debug_notsupp(ctx);
		break;
	    case 'X':
		/* Write target memory with a more efficient encoding */
		debug_notsupp(ctx);
		break;
	    case 'z':
	    case 'Z':
		/* insert (Z) or remove (z) one of the following: */
		switch (pkt[2]) {
		    case '0':
			/* set or clear memory breakpoint */
			debug_notsupp(ctx);
			break;
		    case '1':
			/* set or clear hardware breakpoint */
			debug_notsupp(ctx);
			break;
		    case '2':
			/* set or clear write watchpoint */
			debug_notsupp(ctx);
			break;
		    case '3':
			/* set or clear read watchpoint */
			debug_notsupp(ctx);
			break;
		    case '4':
			/* set or clear access watchpoint */
			debug_notsupp(ctx);
			break;
		    default:
			/* ? */
			debug_notsupp(ctx);
			break;
		}
		break;
	    default:
		debug_notsupp(ctx);
		break;
	}
}