int generate_pkt ( struct pkt *x_pkt, const struct timeval *tv_xmt, int key_id, struct key *pkt_key ) { l_fp xmt; int pkt_len = LEN_PKT_NOMAC; memset(x_pkt, 0, sizeof(struct pkt)); TVTOTS(tv_xmt, &xmt); HTONL_FP(&xmt, &(x_pkt->xmt)); x_pkt->stratum = STRATUM_TO_PKT(STRATUM_UNSPEC); x_pkt->ppoll = 8; /* FIXME! Modus broadcast + adr. check -> bdr. pkt */ set_li_vn_mode(x_pkt, LEAP_NOTINSYNC, 4, 3); if (pkt_key != NULL) { int mac_size = 20; /* max room for MAC */ x_pkt->exten[0] = htonl(key_id); mac_size = make_mac((char *)x_pkt, pkt_len, mac_size, pkt_key, (char *)&x_pkt->exten[1]); if (mac_size) pkt_len += mac_size + 4; } return pkt_len; }
int generate_pkt ( struct pkt *x_pkt, const struct timeval *tv_xmt, int key_id, struct key *pkt_key ) { l_fp xmt_fp; int pkt_len; int mac_size; pkt_len = LEN_PKT_NOMAC; ZERO(*x_pkt); TVTOTS(tv_xmt, &xmt_fp); HTONL_FP(&xmt_fp, &x_pkt->xmt); x_pkt->stratum = STRATUM_TO_PKT(STRATUM_UNSPEC); x_pkt->ppoll = 8; /* FIXME! Modus broadcast + adr. check -> bdr. pkt */ set_li_vn_mode(x_pkt, LEAP_NOTINSYNC, ntpver, 3); if (debug > 0) { printf("generate_pkt: key_id %d, key pointer %p\n", key_id, pkt_key); } if (pkt_key != NULL) { x_pkt->exten[0] = htonl(key_id); mac_size = make_mac(x_pkt, pkt_len, MAX_MDG_LEN, pkt_key, (char *)&x_pkt->exten[1]); if (mac_size > 0) pkt_len += mac_size + KEY_MAC_LEN; #ifdef DEBUG if (debug > 0) { printf("generate_pkt: mac_size is %d\n", mac_size); } #endif } return pkt_len; }
/* Define a function to simulate a server. * This function processes the sent packet according to the server script, * creates a reply packet and pushes the reply packet onto the event queue */ int simulate_server( sockaddr_u *serv_addr, /* Address of the server */ struct interface *inter, /* Interface on which the reply should be inserted */ struct pkt *rpkt /* Packet sent to the server that needs to be processed. */ ) { struct pkt xpkt; /* Packet to be transmitted back to the client */ struct recvbuf rbuf; /* Buffer for the received packet */ Event *e; /* Packet receive event */ server_info *server; /* Pointer to the server being simulated */ script_info *curr_script; /* Current script being processed */ int i; double d1, d2, d3; /* Delays while the packet is enroute */ double t1, t2, t3, t4; /* The four timestamps in the packet */ memset(&xpkt, 0, sizeof(xpkt)); memset(&rbuf, 0, sizeof(rbuf)); /* Search for the server with the desired address */ server = NULL; for (i = 0; i < simulation.num_of_servers; ++i) { fprintf(stderr,"Checking address: %s\n", stoa(simulation.servers[i].addr)); if (memcmp(simulation.servers[i].addr, serv_addr, sizeof(*serv_addr)) == 0) { server = &simulation.servers[i]; break; } } fprintf(stderr, "Received packet for: %s\n", stoa(serv_addr)); if (server == NULL) abortsim("Server with specified address not found!!!"); /* Get the current script for the server */ curr_script = server->curr_script; /* Create a server reply packet. * Masquerade the reply as a stratum-1 server with a GPS clock */ xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, NTP_VERSION, MODE_SERVER); xpkt.stratum = STRATUM_TO_PKT(((u_char)1)); memcpy(&xpkt.refid, "GPS", 4); xpkt.ppoll = rpkt->ppoll; xpkt.precision = rpkt->precision; xpkt.rootdelay = 0; xpkt.rootdisp = 0; /* TIMESTAMP CALCULATIONS t1 t4 \ / d1 \ / d3 \ / t2 ----------------- t3 d2 */ /* Compute the delays */ d1 = poisson(curr_script->prop_delay, curr_script->jitter); d2 = poisson(curr_script->proc_delay, 0); d3 = poisson(curr_script->prop_delay, curr_script->jitter); /* Note: In the transmitted packet: * 1. t1 and t4 are times in the client according to the local clock. * 2. t2 and t3 are server times according to the simulated server. * Compute t1, t2, t3 and t4 * Note: This function is called at time t1. */ LFPTOD(&rpkt->xmt, t1); t2 = server->server_time + d1; t3 = server->server_time + d1 + d2; t4 = t1 + d1 + d2 + d3; /* Save the timestamps */ xpkt.org = rpkt->xmt; DTOLFP(t2, &xpkt.rec); DTOLFP(t3, &xpkt.xmt); xpkt.reftime = xpkt.xmt; /* Ok, we are done with the packet. Now initialize the receive buffer for * the packet. */ rbuf.receiver = receive; /* Function to call to process the packet */ rbuf.recv_length = LEN_PKT_NOMAC; rbuf.recv_pkt = xpkt; rbuf.used = 1; memcpy(&rbuf.srcadr, serv_addr, sizeof(rbuf.srcadr)); memcpy(&rbuf.recv_srcadr, serv_addr, sizeof(rbuf.recv_srcadr)); if ((rbuf.dstadr = malloc(sizeof(*rbuf.dstadr))) == NULL) abortsim("malloc failed in simulate_server"); memcpy(rbuf.dstadr, inter, sizeof(*rbuf.dstadr)); /* rbuf.link = NULL; */ /* Create a packet event and insert it onto the event_queue at the * arrival time (t4) of the packet at the client */ e = event(t4, PACKET); e->rcv_buf = rbuf; enqueue(event_queue, e); /* Check if the time of the script has expired. If yes, delete the script. * If not, re-enqueue the script onto the server script queue */ if (curr_script->duration > simulation.sim_time && !empty(server->script)) { printf("Hello\n"); /* * For some reason freeing up the curr_script memory kills the * simulation. Further debugging is needed to determine why. * free_node(curr_script); */ curr_script = dequeue(server->script); } return (0); }