#include <netinet/in.h>
#include "kernel.h"

extern struct base                      **cell;

extern struct pack_vect			*packs2bsnt;

int					sockd = -1;

void send_it(char *pack,int psize){
  struct sockaddr_in sin;
  char  on = 1;
  int   status = 0;
  char  *dst = pack+16;

  if(sockd < 0){
    sockd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
    if(sockd < 0){
      printf("Couldn't open a socket...\n");
      exit(0);
    }
  }
  
  memset(&sin,0,sizeof(sin));
  sin.sin_family = AF_INET;
  sin.sin_port = 0;
  memcpy(&sin.sin_addr.s_addr,dst,4);
  
  setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));
  status = sendto(sockd,pack,psize,0x0,(struct sockaddr *)&sin,sizeof(sin));
}

int finish_pack(u_int32_t state){
  struct send	*snd;
  int i,status_1,status_2;
  u_int32_t	arg_1,arg_2,result;

  snd = (struct send *)cell[state]->arg;
 
  if(snd->nobt != 0){
    for(i=0;i<snd->nobt;i++){
      switch(snd->but[i]->operation){
        case NOP:
          status_1 = get_argument(snd,cell,snd->but[i],snd->packet_id,0,&arg_1,0,1);
	  if(!status_1){
	    carry_argument(snd,snd->but[i],snd->packet_id,arg_1);
          }else if(status_1 == RECEIVED_PACKET){
	  	  printf("The packet pointed by the argument has not arrived yet!\n");
		  /* In this case, the argument used is considered zero */
		  carry_argument(snd,snd->but[i],snd->packet_id,0);
	        }else{
	           printf("Unexpected error! It should be unreachable!(please contact the guy who's done it)\n");
		   exit(0);
                 }
        break;
        default:
          status_1 = get_argument(snd,cell,snd->but[i],snd->packet_id,0,&arg_1,0,1);
	  status_2 = get_argument(snd,cell,snd->but[i],snd->packet_id,1,&arg_2,0,1);
	  if(!status_1 && !status_2){
	    calc_args(snd->but[i]->operation,arg_1,arg_2,&result);
	    carry_argument(snd,snd->but[i],snd->packet_id,result);
          }else if(status_1 == RECEIVED_PACKET && status_2 == 0){
		  printf("The packet pointed by the first argument has not arrived yet!\n");
		  /* In this case, the first argument is considered zero */
		  calc_args(snd->but[i]->operation,0,arg_2,&result);
		  carry_argument(snd,snd->but[i],snd->packet_id,result);
	        }else if(status_1 == 0 && status_2 == RECEIVED_PACKET){
		      printf("The packet pointed by the second argument has not arrived yet!\n");
		      /*   In this case, the operation is not accomplished and only the 
		       * first agument is considered
		       */
		      carry_argument(snd,snd->but[i],snd->packet_id,arg_1);
		      }else{
		         printf("Unexpected error! It should be unreachable!(please contact the guy who's done it)\n");
		         exit(0);
		       }
      }
    }
  }
  return 0;
}
