int main(int argc,char *argv[]) { int i; key_t key; // 内存队列 key_t shmid; pid_t pid; key = 666; if (argc !=2) return 1; g_szIfName = argv[1]; //create memory queue qid=msgget(key,IPC_CREAT|0666); if (qid<0) { perror( "msgget" ); exit; } printf ("qid=%d",qid); fd = ethdump_initSocket(); if(0>fd) { return -1; } if( (shmid = shmget(IPC_PRIVATE, SHM_SIZE, S_IRUSR|S_IWUSR)) == -1 ) //(1)申请一个共享内存 { fprintf(stderr, "Create Share Memory Error:%s/n/a", strerror(errno)); exit(1); } pid = fork(); if (pid>0){ //主进程 cap_packet(shmid); } else if(pid ==0){//子进程 //usleep(10000); save_packet(shmid); } //close(fd); return 0; }
int main(int argc, char *argv[]) { struct sockaddr_in si_me, si_other; int sk; socklen_t slen = sizeof(si_other); int len, ret; fd_set readsock; struct packet p; char buf[PAYLOAD_SIZE]; char log_file[LINE_LENGTH]; char serial_file[LINE_LENGTH]; unsigned int crc32_value; struct hostent *hostentry; unsigned int i; int mask; memset(log_file, 0, LINE_LENGTH); memset(serial_file, 0, LINE_LENGTH); memset(buf, 0, PAYLOAD_SIZE); if (argv[1] != NULL) { if(!strcmp(argv[1], "debug")) mask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_DEBUG)); else mask = LOG_MASK(LOG_ERR); } else mask = LOG_MASK(LOG_ERR); /* Our process ID and Session ID */ pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(1); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { save_pid(PID_FILE, pid); exit(0); } /* Change the file mode mask */ umask(0); /* Open any logs here */ /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { /* Log the failure */ exit(1); } /* Change the current working directory */ if ((chdir("/")) < 0) { /* Log the failure */ exit(1); } /* Close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); /* Daemon-specific initialization goes here */ openlog("USBlogger server", LOG_PID | LOG_CONS | LOG_NDELAY | LOG_NOWAIT, LOG_LOCAL0); setlogmask(mask); ret = parse_config(CONFIG_FILE, log_file, serial_file, CONFIG_NUM_PARAMS); if (ret) { syslog(LOG_ERR, "Something wrong happened while reading configuration. Please check config file - %s", CONFIG_FILE); exit(1); } /* Initialize the socket to recv messages */ sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sk == -1) { syslog(LOG_ERR, "socket creation failed"); exit(1); } memset(&si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; si_me.sin_port = htons(PORT); si_me.sin_addr.s_addr = htonl(INADDR_ANY); ret = bind(sk, (struct sockaddr *)&si_me, sizeof(si_me)); if (ret == -1) { syslog(LOG_ERR, "bind failed"); exit(1); } /* The Big Loop */ while (1) { FD_ZERO(&readsock); FD_SET(sk, &readsock); ret = select(FD_SETSIZE, &readsock, NULL, NULL, NULL); if (ret == -1) { syslog(LOG_ERR, "error in select() at main loop"); exit(1); } else if (ret > 0) { if (FD_ISSET(sk, &readsock)) { len = recvfrom(sk, buf, PAYLOAD_SIZE, 0, (struct sockaddr *)&si_other, &slen); if (len == -1) { syslog(LOG_ERR, "recvfrom returned an error"); continue; } syslog(LOG_DEBUG, "len = %d, Received the message from client ... ", len); // for(i = 0; i < len; i++) // putchar(buf[i]); // putchar('\n'); ret = parse_packet(&p, buf, len); if(ret) { syslog(LOG_ERR, "parser found an error during parsing a packet"); //clear_packet(&p); memset(buf, 0, PAYLOAD_SIZE); continue; } print_packet(&p); ret = is_serial_allowed(serial_file, p.fields[2].value_val); if (ret != 0) { //serial is not in the list, so saving log save_packet(log_file, &p); } // serial in the list, nothing to do crc32_value = crc32(buf, len); syslog(LOG_DEBUG, "CRC32 value of the message is = %x", crc32_value); hostentry = gethostbyname(p.fields[1].value_val); if(hostentry == NULL) { syslog(LOG_ERR, "Resolving hostname failed"); clear_packet(&p); memset(buf, 0, PAYLOAD_SIZE); continue; } syslog(LOG_DEBUG, "Client IP: %s", inet_ntoa(*((struct in_addr *)hostentry->h_addr_list[0])) ); clear_packet(&p); memset(buf, 0, PAYLOAD_SIZE); ret = send_buffer_to_client(sk, (struct in_addr *)hostentry->h_addr_list[0], (char *)&crc32_value, sizeof(crc32_value)); /* // Any device plugged into server if (bus_msg->msgtype == '1') { tableret = add_to_table(bus_msg); if (tableret != 0) { printf("No hub any more.\n"); return -1; } print_table(); printf("Received a bus (%s) from %s\n", bus_msg->busname, inet_ntoa(si_other.sin_addr)); sprintf(cmd, "usbip_attach "); strcat(cmd, inet_ntoa(si_other.sin_addr)); strcat(cmd, " "); strcat(cmd, bus_msg->busname); system(cmd); } // Any device unplugged from server if (bus_msg->msgtype == '0') { char str[2]; tableret = del_from_table(bus_msg); if (tableret == -1) { printf("Device not found.\n"); return -1; } print_table(); printf("Received a bus (%s) from %s\n", bus_msg->busname, inet_ntoa(si_other.sin_addr)); sprintf(cmd, "usbip_detach "); sprintf(str, "%d", tableret); strcat(cmd, str); system(cmd); } */ } } } close(sk); return 0; }
// Handler for received BOOTP/DHCP packets static void bootp_handler(udp_socket_t *skt, char *buf, int len, ip_route_t *src_route, word src_port) { bootp_header_t *b; #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP int txSize; int type; bootp_header_t txpkt; unsigned expected = 0; #endif b = (bootp_header_t *) buf; // only accept BOOTP REPLY responses if (b->bp_op != BOOTREPLY) return; // must be sent to me if (memcmp(b->bp_chaddr, __local_enet_addr, b->bp_hlen)) return; // verify XID if (b->bp_xid != xid) return; #if !defined(CYGSEM_REDBOOT_NETWORKING_DHCP) // simple BOOTP - this is all there is! debug_printf("BOOTP recv: REPLY\n"); if (dhcpState != DHCP_DONE) { save_packet(b, len); parseConfig(b, len); NewDhcpState(DHCP_DONE); } #else // DHCP support is enabled... // Check to see that it's a DHCP packet with a DHCP type field type = -1; if (!memcmp(b->bp_vend, dhcpCookie, sizeof dhcpCookie)) { unsigned char *p = b->bp_vend + 4; while (p < (unsigned char *)b + len) { if (*p == TAG_DHCP_MESS_TYPE) { type = p[2]; break; } p += p[1] + 2; } } if (type == -1) { // apparently we have a BOOTP (but not not DHCP) server debug_printf("DHCP recv: BOOTP-REPLY -- falling back to BOOTP mode\n"); if (dhcpState != DHCP_DONE) { save_packet(b, len); parseConfig(b, len); NewDhcpState(DHCP_DONE); } return; } // it's a real DHCP packet debug_printf("DHCP recv: %s [%d]\n", dhcpTypeString[type], type); switch (dhcpState) { case DHCP_WAITING_FOR_OFFER: if (type == (expected = DHCP_MESS_TYPE_OFFER)) { prep_bootp_request(&txpkt); txSize = prep_dhcp_request(&txpkt, b); debug_printf("DHCP send: REQUEST\n"); NewDhcpState(DHCP_WAITING_FOR_ACK); __udp_send((char *)&txpkt, txSize, (ip_route_t *)&broadcast, IPPORT_BOOTPS, IPPORT_BOOTPC); return; } break; case DHCP_WAITING_FOR_ACK: if (type == (expected = DHCP_MESS_TYPE_ACK)) { save_packet(b, len); parseConfig(b, len); NewDhcpState(DHCP_DONE); return; } break; default: debug_printf("DHCP packet ignored\n"); return; } if (type == DHCP_MESS_TYPE_NAK && dhcpState != DHCP_DONE) { NewDhcpState(DHCP_FAILED); return; } debug_printf("DHCP packet ignored -- expected %d[%s]\n", expected, dhcpTypeString[expected]); #endif }
int fetcher_callback(struct nfq_q_handle *hq, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) { u_int32_t id = 0; struct iphdr *iph = NULL; struct tcphdr *tcph = NULL; struct session *thissession = NULL; struct packet *thispacket = NULL; struct nfqnl_msg_packet_hdr *ph; struct timeval tv; __u32 largerIP, smallerIP, remoteID; __u16 largerIPPort, smallerIPPort, mms; int ret; int incomingQueueNum; unsigned char *originalpacket = NULL; char strIP[20]; // for debugging purposes char saddr[INET_ADDRSTRLEN]; char daddr[INET_ADDRSTRLEN]; ph = nfq_get_msg_packet_hdr(nfa); if (ph) { id = ntohl(ph->packet_id); } ret = nfq_get_payload(nfa, &originalpacket); if (servicestate >= RUNNING) { iph = (struct iphdr *) originalpacket; thefetcher.metrics.bytesin += ntohs(iph->tot_len); /* We need to double check that only TCP packets get accelerated. */ /* This is because we are working from the Netfilter QUEUE. */ /* User could QUEUE UDP traffic, and we cannot accelerate UDP. */ if ((iph->protocol == IPPROTO_TCP) && (id != 0)) { tcph = (struct tcphdr *) (((u_int32_t *) originalpacket) + iph->ihl); // for debugging purpose inet_ntop(AF_INET, &iph->saddr, saddr, INET_ADDRSTRLEN); inet_ntop(AF_INET, &iph->daddr, daddr, INET_ADDRSTRLEN); /* Check what IP address is larger. */ sort_sockets(&largerIP, &largerIPPort, &smallerIP, &smallerIPPort, iph->saddr, tcph->source, iph->daddr, tcph->dest); // remoteID = (__u32) __get_tcp_option((__u8 *)originalpacket,32); if (__get_tcp_option((__u8 *)originalpacket,32) ) { unsigned char *tcpdata = (unsigned char *) tcph + tcph->doff * 4; // Find starting location of the TCP data. unsigned int incLen = (__u16)(ntohs(iph->tot_len) - iph->ihl * 4) - tcph->doff * 4; if (incLen < sizeof(OpennopHeader)) { LOGERROR(lc_fetcher, "detected opennop option but incoming TCP data length less than opennop header length!!!!"); return nfq_set_verdict(hq, id, NF_DROP,0,NULL); } pOpennopHeader oh = (pOpennopHeader) tcpdata; remoteID = oh->opennopID; incomingQueueNum = oh->queuenum; if (oh->pattern != OPENNOP_PATTERN) { LOGERROR(lc_fetcher, "option 32 found but bad pattern!!!"); return nfq_set_verdict(hq, id, NF_DROP,0,NULL); } } else remoteID = 0; inet_ntop(AF_INET, &remoteID, strIP, INET_ADDRSTRLEN); //LOGDEBUG(lc_fetcher, "The accellerator ID is:%s", strIP); if (remoteID == 0) { LOGTRACE(lc_fetcher, "Packet from CLIENT: SYN=%d/FIN=%d/ACK=%d/RST=%d, %s:%d->%s:%d, IP_Id=%d, NFQ_Id=%d, TCP_seq=%u, ACK_seq=%u, Total_len=%d, TCP_hlen=%d, IP_hlen=%d, Data_len=%d", tcph->syn, tcph->fin, tcph->ack, tcph->rst, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest), ntohs(iph->id), id, ntohl(tcph->seq), ntohl(tcph->ack_seq), ntohs(iph->tot_len), tcph->doff * 4, iph->ihl * 4, ntohs(iph->tot_len) - tcph->doff * 4 - iph->ihl * 4); } else { LOGTRACE(lc_fetcher, "Packet from %s: SYN=%d/FIN=%d/ACK=%d/RST=%d, %s:%d->%s:%d, IP_Id=%d, NFQ_Id=%d, TCP_seq=%u, ACK_seq=%u, Total_len=%d, TCP_hlen=%d, IP_hlen=%d, Data_len=%d", strIP, tcph->syn, tcph->fin, tcph->ack, tcph->rst, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest), ntohs(iph->id), id, ntohl(tcph->seq), ntohl(tcph->ack_seq), ntohs(iph->tot_len), tcph->doff * 4, iph->ihl * 4, ntohs(iph->tot_len) - tcph->doff * 4 - iph->ihl * 4); } thissession = getsession(largerIP, largerIPPort, smallerIP, smallerIPPort); // Check for an outstanding syn. // if (thissession != NULL) { // LOGDEBUG(lc_sesman_check, "****** [SESSION MANAGER] LargerIPseq: %u SmallerIPseq %u, TCP_seq=%u", thissession->largerIPseq, thissession->smallerIPseq, ntohl(tcph->seq)); // } /* Check if this a SYN packet to identify a new session. */ /* This packet will not be placed in a work queue, but */ /* will be accepted here because it does not have any data. */ //if ((tcph->syn == 1) && (tcph->ack == 0)) { if (tcph->syn == 1) { // // SYN segment // if (tcph->ack == 0) { if (remoteID == 0) { LOGDEBUG(lc_fetcher, "SYN from CLIENT: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); } else { LOGDEBUG(lc_fetcher, "SYN from %s: %s:%d->%s:%d", strIP, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); } } else { if (remoteID == 0) { LOGDEBUG(lc_fetcher, "SYN+ACK from CLIENT: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); } else { LOGDEBUG(lc_fetcher, "SYN+ACK from %s: %s:%d->%s:%d", strIP, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); } } if (thissession == NULL) { if (remoteID != 0) thissession = insertsession(largerIP, largerIPPort, smallerIP, smallerIPPort, incomingQueueNum); // Insert into sessions list. else thissession = insertsession(largerIP, largerIPPort, smallerIP, smallerIPPort, -1); // Insert into sessions list. if (remoteID == 0) { LOGDEBUG(lc_fetcher, "New session from CLIENT created: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ) } else { LOGDEBUG(lc_fetcher, "New session from %s created: %s:%d->%s:%d", strIP, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ) }; } /* We need to check for NULL to make sure */ /* that a record for the session was created */ if (thissession != NULL) { gettimeofday(&tv,NULL); // Get the time from hardware. thissession->lastactive = tv.tv_sec; // Update the session timestamp. sourceisclient(largerIP, iph, thissession, tcph->ack == 0); updateseq(largerIP, iph, tcph, thissession); updateseqnumber(largerIP, iph, tcph, thissession); if (remoteID == 0) { // Accelerator ID was not found. mms = __get_tcp_option((__u8 *)originalpacket,2); if (mms > 68) { if (__set_tcp_option((__u8 *)originalpacket,2,4,mms - 68) == -1) {// Reduce the MSS. LOGERROR(lc_fetcher, "Cannot reduce MSS in 68, fetcher.c, packet is a SYN, IP datagram ID %x, current value of TCP doff %d",ntohs(iph->id), tcph->doff); } if (__set_tcp_option((__u8 *)originalpacket,32,3,1) == -1) { // Add the Accelerator ID to this packet. LOGERROR(lc_fetcher, "Cannot set opennop option to 1, fetcher.c, packet is a SYN, IP datagram ID %x, current value of TCP doff %d",ntohs(iph->id), tcph->doff); } else { unsigned char *tcpdata = (unsigned char *) tcph + tcph->doff * 4; // Find starting location of the TCP data. pOpennopHeader oh = (pOpennopHeader) tcpdata; oh->opennopID = localID; oh->seqNo = 0; oh->compression = 0; oh->deduplication = 0; oh->reasonForNoOptimization = NOT_RELEVANT; oh->pattern = OPENNOP_PATTERN; oh->queuenum = thissession->queue; iph->tot_len = htons(ntohs(iph->tot_len)+sizeof(OpennopHeader)); LOGTRACE(lc_fetcher, "Adding opennop header to SYN packet: IP total length=%d",ntohs(iph->tot_len)); } saveacceleratorid(largerIP, localID, iph, thissession); /* * Changing anything requires the IP and TCP * checksum to need recalculated. */ checksum(originalpacket); } } else { // Accelerator ID was found. //LOGDEBUG(lc_fetcher, "New session from %s created: %s:%d->%s:%d", strIP, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); if (__set_tcp_option((__u8 *)originalpacket,32,3,0) == -1) { LOGERROR(lc_fetcher, "Cannot set opennop option to 0, fetcher.c, packet is a SYN, IP datagram ID %x, current value of TCP doff %d",ntohs(iph->id), tcph->doff); } else iph->tot_len = htons(ntohs(iph->tot_len)-sizeof(OpennopHeader)); checksum(originalpacket); saveacceleratorid(largerIP, remoteID, iph, thissession); } if (tcph->ack == 0) { thissession->state = TCP_SYN_SENT; LOGDEBUG(lc_fetcher, "Session state set to TCP_SYN_SENT"); } else { thissession->state = TCP_ESTABLISHED; LOGDEBUG(lc_fetcher, "Session state set to TCP_ESTABLISHED"); } } /* Before we return let increment the packets counter. */ thefetcher.metrics.packets++; /* This is the last step for a SYN packet. */ /* accept all SYN packets. */ return nfq_set_verdict(hq, id, NF_ACCEPT, ntohs(iph->tot_len), (unsigned char *)originalpacket); // } else if (tcph->rst == 1) { // // RESET segment // // LOGDEBUG(lc_fetcher, "Session RESET %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest)); // clearsession(thissession); // fruiz // // thissession = NULL; /* Before we return let increment the packets counter. */ // thefetcher.metrics.packets++; // return nfq_set_verdict(hq, id, NF_ACCEPT, 0, NULL); // } else if (tcph->fin == 1) { // // // // // FIN segment // // // LOGDEBUG(lc_fetcher, "FIN packet: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest)); // if (thissession != NULL) { // switch (thissession->state) { // case TCP_ESTABLISHED: // thissession->state = TCP_CLOSING; // LOGDEBUG(lc_fetcher, "Session half closed: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest)); // break; // case TCP_CLOSING: // clearsession(thissession); // LOGDEBUG(lc_fetcher, "Session full closed: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest)); // break; // } // } // // /* Before we return let increment the packets counter. */ // thefetcher.metrics.packets++; // LOGDEBUG(lc_fetcher, "hq=%d, id=%d", hq, id); // int res = nfq_set_verdict(hq, id, NF_ACCEPT, ntohs(iph->tot_len), (unsigned char *)originalpacket); // LOGDEBUG(lc_fetcher, "Returning FIN packet %d", res); // //return nfq_set_verdict(hq, id, NF_ACCEPT, 0, NULL); // //return nfq_set_verdict(hq, id, NF_ACCEPT, ntohs(iph->tot_len), (unsigned char *)originalpacket); // return res; } else { // // DATA or FIN segment // if (thissession != NULL) { // DATA segment in an active session //LOGDEBUG(lc_sesman_check, "[SESSION MANAGER] LargerIPseq: %u SmallerIPseq %u", thissession->largerIPseq, thissession->smallerIPseq); gettimeofday(&tv,NULL); // Get the time from hardware. thissession->lastactive = tv.tv_sec; // Update the active timer. thissession->deadcounter = 0; // Reset the dead counter. if (__get_tcp_option((__u8 *)originalpacket,32) == 2) { // Keepalive, can drop LOGDEBUG(lc_fetcher, "Received keepalive: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); return nfq_set_verdict(hq, id, NF_DROP,0,NULL); } thispacket = get_freepacket_buffer(); if (thispacket != NULL){ save_packet(thispacket,hq, id, ret, (__u8 *)originalpacket, thissession); if (remoteID == 0){ LOGTRACE(lc_fetcher, "Packet sent to optimize"); optimize_packet(thissession->queue, thispacket); } else { LOGTRACE(lc_fetcher, "Packet sent to deoptimize"); deoptimize_packet(thissession->queue, thispacket); } } else { LOGERROR(lc_fetcher, "Failed getting packet buffer for processing"); } /* Before we return let increment the packets counter. */ thefetcher.metrics.packets++; return 0; } else { // DATA segment and no active session exists int data_len = ntohs(iph->tot_len) - tcph->doff * 4 - iph->ihl * 4; if (data_len > 0) { LOGDEBUG(lc_fetcher, "No session found for: SYN=%d/FIN=%d/ACK=%d/RST=%d, %s:%d->%s:%d, Opt_ID=%s, IP_Id=%d, NFQ_Id=%d, Total_len=%d, TCP_hlen=%d, IP_hlen=%d, Data_len=%d", tcph->syn, tcph->fin, tcph->ack, tcph->rst, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest), strIP, ntohs(iph->id), id, ntohs(iph->tot_len), tcph->doff * 4, iph->ihl * 4, ntohs(iph->tot_len) - tcph->doff * 4 - iph->ihl * 4); } /* We only want to create new sessions for active sessions. */ /* This means we exclude anything accept ACK packets. */ if (tcph->ack == 1) { if (remoteID != 0) { // Detected remote Accelerator so it is safe to add this session. thissession = insertsession(largerIP, largerIPPort, smallerIP, smallerIPPort, incomingQueueNum); // Insert into sessions list. if (thissession != NULL) { // Test to make sure the session was added. LOGDEBUG(lc_fetcher, "Created NEW session for: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); thissession->state = TCP_ESTABLISHED; saveacceleratorid(largerIP, remoteID, iph, thissession); thispacket = get_freepacket_buffer(); if (thispacket != NULL){ save_packet(thispacket,hq, id, ret, (__u8 *)originalpacket, thissession); updateseqnumber(largerIP, iph, tcph, thissession); //Update the stored TCP sequence number deoptimize_packet(thissession->queue, thispacket); } else { LOGERROR(lc_fetcher, "Failed getting packet buffer for deoptimization."); } /* Before we return let increment the packets counter. */ thefetcher.metrics.packets++; return 0; } else { LOGERROR(lc_fetcher, "Failed to create session for: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); } } } /* Before we return let increment the packets counter. */ thefetcher.metrics.packets++; //LOGERROR(lc_fetcher, "Unknown packet: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); return nfq_set_verdict(hq, id, NF_ACCEPT, ntohs(iph->tot_len), (unsigned char *)originalpacket); } } } else { /* Packet was not a TCP Packet or ID was 0. */