void send_request(int s) { /* Print the request packet. */ printf("Sending to %s", inet_ntoa(sin_server.sin_addr)); bootp_print((struct bootp *)sndbuf, snaplen, sin_from.sin_port, 0); putchar('\n'); /* Send the request packet. */ if (sendto(s, sndbuf, snaplen, 0, (struct sockaddr *) &sin_server, sizeof(sin_server)) < 0) { perror("sendto server"); exit(1); } }
int main(int argc, char **argv) { struct bootp *bp; struct servent *sep; struct hostent *hep; char *servername = NULL; char *vendor_file = NULL; char *bp_file = NULL; socklen_t fromlen; int s; /* Socket file descriptor */ int n, recvcnt; int use_hwa = 0; int32 vend_magic; int32 xid; struct pollfd set[1]; progname = strrchr(argv[0], '/'); if (progname) progname++; else progname = argv[0]; argc--; argv++; if (debug) printf("%s: version %s.%d\n", progname, VERSION, PATCHLEVEL); /* * Verify that "struct bootp" has the correct official size. * (Catch evil compilers that do struct padding.) */ assert(sizeof(struct bootp) == BP_MINPKTSZ); sndbuf = malloc(BUFLEN); rcvbuf = malloc(BUFLEN); if (!sndbuf || !rcvbuf) { printf("malloc failed\n"); exit(1); } /* default magic number */ bcopy(vm_rfc1048, (char*)&vend_magic, 4); /* Handle option switches. */ while (argc > 0) { if (argv[0][0] != '-') break; switch (argv[0][1]) { case 'f': /* File name to reqest. */ if (argc < 2) goto error; argc--; argv++; bp_file = *argv; break; case 'h': /* Use hardware address. */ use_hwa = 1; break; case 'm': /* Magic number value. */ if (argc < 2) goto error; argc--; argv++; vend_magic = inet_addr(*argv); break; error: default: (void)fprintf(stderr, usage, getprogname()); exit(1); } argc--; argv++; } /* Get server name (or address) for query. */ if (argc > 0) { servername = *argv; argc--; argv++; } /* Get optional vendor-data-template-file. */ if (argc > 0) { vendor_file = *argv; argc--; argv++; } if (!servername) { printf("missing server name.\n"); (void)fprintf(stderr, usage, getprogname()); exit(1); } /* * Create a socket. */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } /* * Get server's listening port number */ sep = getservbyname("bootps", "udp"); if (sep) { bootps_port = ntohs((u_short) sep->s_port); } else { fprintf(stderr, "udp/bootps: unknown service -- using port %d\n", IPPORT_BOOTPS); bootps_port = (u_short) IPPORT_BOOTPS; } /* * Set up server socket address (for send) */ if (servername) { if (inet_aton(servername, &sin_server.sin_addr) == 0) { hep = gethostbyname(servername); if (!hep) { fprintf(stderr, "%s: unknown host\n", servername); exit(1); } memcpy(&sin_server.sin_addr, hep->h_addr, sizeof(sin_server.sin_addr)); } } else { /* Get broadcast address */ /* XXX - not yet */ sin_server.sin_addr.s_addr = INADDR_ANY; } sin_server.sin_family = AF_INET; sin_server.sin_port = htons(bootps_port); /* * Get client's listening port number */ sep = getservbyname("bootpc", "udp"); if (sep) { bootpc_port = ntohs(sep->s_port); } else { fprintf(stderr, "udp/bootpc: unknown service -- using port %d\n", IPPORT_BOOTPC); bootpc_port = (u_short) IPPORT_BOOTPC; } /* * Set up client socket address (for listen) */ sin_client.sin_family = AF_INET; sin_client.sin_port = htons(bootpc_port); sin_client.sin_addr.s_addr = INADDR_ANY; /* * Bind client socket to BOOTPC port. */ if (bind(s, (struct sockaddr *) &sin_client, sizeof(sin_client)) < 0) { perror("bind BOOTPC port"); if (errno == EACCES) fprintf(stderr, "You need to run this as root\n"); exit(1); } /* * Build a request. */ bp = (struct bootp *) sndbuf; bzero(bp, sizeof(*bp)); bp->bp_op = BOOTREQUEST; xid = (int32) getpid(); bp->bp_xid = (u_int32) htonl(xid); if (bp_file) strlcpy(bp->bp_file, bp_file, sizeof(bp->bp_file)); /* * Fill in the hardware address (or client IP address) */ if (use_hwa) { struct ifreq *ifr; ifr = getif(s, &sin_server.sin_addr); if (!ifr) { printf("No interface for %s\n", servername); exit(1); } if (getether(ifr->ifr_name, (char *)eaddr)) { printf("Can not get ether addr for %s\n", ifr->ifr_name); exit(1); } /* Copy Ethernet address into request packet. */ bp->bp_htype = 1; bp->bp_hlen = 6; bcopy(eaddr, bp->bp_chaddr, bp->bp_hlen); } else { /* Fill in the client IP address. */ gethostname(hostname, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; hep = gethostbyname(hostname); if (!hep) { printf("Can not get my IP address\n"); exit(1); } bcopy(hep->h_addr, &bp->bp_ciaddr, hep->h_length); } /* * Copy in the default vendor data. */ bcopy((char*)&vend_magic, bp->bp_vend, 4); if (vend_magic) bp->bp_vend[4] = TAG_END; /* * Read in the "options" part of the request. * This also determines the size of the packet. */ snaplen = sizeof(*bp); if (vendor_file) { int fd = open(vendor_file, 0); if (fd < 0) { perror(vendor_file); exit(1); } /* Compute actual space for options. */ n = BUFLEN - sizeof(*bp) + BP_VEND_LEN; n = read(fd, bp->bp_vend, n); close(fd); if (n < 0) { perror(vendor_file); exit(1); } printf("read %d bytes of vendor template\n", n); if (n > BP_VEND_LEN) { printf("warning: extended options in use (len > %d)\n", BP_VEND_LEN); snaplen += (n - BP_VEND_LEN); } } /* * Set globals needed by print_bootp * (called by send_request) */ packetp = (unsigned char *) eaddr; snapend = (unsigned char *) sndbuf + snaplen; /* Send a request once per second while waiting for replies. */ recvcnt = 0; bp->bp_secs = secs = 0; send_request(s); set[0].fd = s; set[0].events = POLLIN; while (1) { n = poll(set, 1, WAITSECS * 1000); if (n < 0) { perror("poll"); break; } if (n == 0) { /* * We have not received a response in the last second. * If we have ever received any responses, exit now. * Otherwise, bump the "wait time" field and re-send. */ if (recvcnt > 0) exit(0); secs += WAITSECS; if (secs > MAXWAIT) break; bp->bp_secs = htons(secs); send_request(s); continue; } fromlen = sizeof(sin_from); n = recvfrom(s, rcvbuf, BUFLEN, 0, (struct sockaddr *) &sin_from, &fromlen); if (n <= 0) { continue; } if (n < (int)sizeof(struct bootp)) { printf("received short packet\n"); continue; } recvcnt++; /* Print the received packet. */ printf("Recvd from %s", inet_ntoa(sin_from.sin_addr)); /* set globals needed by bootp_print() */ snaplen = n; snapend = (unsigned char *) rcvbuf + snaplen; bootp_print((struct bootp *)rcvbuf, n, sin_from.sin_port, 0); putchar('\n'); /* * This no longer exits immediately after receiving * one response because it is useful to know if the * client might get multiple responses. This code * will now listen for one second after a response. */ } fprintf(stderr, "no response from %s\n", servername); exit(1); }
char * RaDumpUserBuffer (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus, int ind, int len) { struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX]; unsigned short sport = 0, dport = 0; int type, proto, process = 0; struct ArgusDataStruct *user = NULL; u_char buf[MAXSTRLEN], *bp = NULL, dchr; int slen = 0, done = 0; switch (ind) { case ARGUS_SRCUSERDATA_INDEX: dchr = 's'; break; case ARGUS_DSTUSERDATA_INDEX: dchr = 'd'; break; } if ((user = (struct ArgusDataStruct *)argus->dsrs[ind]) != NULL) { bp = (u_char *) &user->array; slen = (user->hdr.argus_dsrvl16.len - 2 ) * 4; slen = (user->count < slen) ? user->count : slen; slen = (slen > len) ? len : slen; snapend = bp + slen; } if (flow != NULL) { switch (flow->hdr.subtype & 0x3F) { case ARGUS_FLOW_CLASSIC5TUPLE: { switch (type = flow->hdr.argus_dsrvl8.qual) { case ARGUS_TYPE_IPV4: switch (flow->ip_flow.ip_p) { case IPPROTO_TCP: case IPPROTO_UDP: { proto = flow->ip_flow.ip_p; sport = flow->ip_flow.sport; dport = flow->ip_flow.dport; process++; break; } case IPPROTO_IGMP: { struct ArgusMetricStruct *metric = (void *)argus->dsrs[ARGUS_METRIC_INDEX]; if ((metric != NULL) && (((ind == ARGUS_SRCUSERDATA_INDEX) && metric->src.pkts) || ((ind == ARGUS_DSTUSERDATA_INDEX) && metric->dst.pkts))) { igmp_print(bp, slen); done++; break; } } case IPPROTO_PIM: { struct ArgusMetricStruct *metric = (void *)argus->dsrs[ARGUS_METRIC_INDEX]; if ((metric != NULL) && (((ind == ARGUS_SRCUSERDATA_INDEX) && metric->src.pkts) || ((ind == ARGUS_DSTUSERDATA_INDEX) && metric->dst.pkts))) { pim_print(bp, slen); done++; break; } } } break; case ARGUS_TYPE_IPV6: { switch (flow->ipv6_flow.ip_p) { case IPPROTO_TCP: case IPPROTO_UDP: { proto = flow->ipv6_flow.ip_p; sport = flow->ipv6_flow.sport; dport = flow->ipv6_flow.dport; process++; break; } case IPPROTO_PIM: { struct ArgusMetricStruct *metric = (void *)argus->dsrs[ARGUS_METRIC_INDEX]; if ((metric != NULL) && (((ind == ARGUS_SRCUSERDATA_INDEX) && metric->src.pkts) || ((ind == ARGUS_DSTUSERDATA_INDEX) && metric->dst.pkts))) { pim_print(bp, slen); done++; break; } } } break; } case ARGUS_TYPE_ARP: { if (ind == ARGUS_SRCUSERDATA_INDEX) { arp_src_print(parser, argus); } if (ind == ARGUS_DSTUSERDATA_INDEX) { arp_dst_print(parser, argus); } done++; break; } /* struct ArgusMacFlow { struct ether_header ehdr; unsigned char dsap, ssap; }; */ case ARGUS_TYPE_ETHER: { if (flow != NULL) if ((flow->mac_flow.mac_union.ether.ssap == LLCSAP_BPDU) && (flow->mac_flow.mac_union.ether.dsap == LLCSAP_BPDU)) stp_print (bp, slen); done++; break; } } } } } if (process && bp) { *(int *)&buf = 0; #define ISPORT(p) (dport == (p) || sport == (p)) switch (proto) { case IPPROTO_TCP: { if (ISPORT(BGP_PORT)) bgp_print(bp, slen); else if (ISPORT(TELNET_PORT)) telnet_print(bp, slen); else if (ISPORT(PPTP_PORT)) pptp_print(bp, slen); else if (ISPORT(NETBIOS_SSN_PORT)) nbt_tcp_print(bp, slen); else if (ISPORT(BEEP_PORT)) beep_print(bp, slen); else if (ISPORT(NAMESERVER_PORT) || ISPORT(MULTICASTDNS_PORT)) ns_print(bp + 2, slen - 2, 0); else if (ISPORT(MSDP_PORT)) msdp_print(bp, slen); else if (ISPORT(LDP_PORT)) ldp_print(bp, slen); else { int elen = 0; parser->eflag = ArgusThisEflag; elen = ArgusEncode (parser, (const char *)bp, NULL, slen, ArgusBuf, sizeof(ArgusBuf)); parser->eflag = ARGUS_HEXDUMP; } break; } case IPPROTO_UDP: { if (ISPORT(NAMESERVER_PORT)) ns_print(bp, slen, 0); else if (ISPORT(MULTICASTDNS_PORT)) ns_print(bp, slen, 1); else if (ISPORT(NTP_PORT)) ntp_print(bp, slen); else if (ISPORT(LDP_PORT)) ldp_print(bp, slen); else if (ISPORT(RADIUS_PORT) || ISPORT(RADIUS_NEW_PORT) || ISPORT(RADIUS_ACCOUNTING_PORT) || ISPORT(RADIUS_NEW_ACCOUNTING_PORT) ) radius_print(bp, slen); else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT)) krb_print(bp, slen); else if (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT)) snmp_print(bp, slen); else if (ISPORT(TIMED_PORT)) timed_print(bp, slen); else if (ISPORT(TFTP_PORT)) tftp_print(bp, slen); else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS)) bootp_print(bp, slen); else if (ISPORT(RIP_PORT)) rip_print(bp, slen); else if (ISPORT(AODV_PORT)) aodv_print(bp, slen, 0); else if (ISPORT(L2TP_PORT)) l2tp_print(bp, slen); else if (ISPORT(SYSLOG_PORT)) syslog_print(bp, slen); else if (ISPORT(LMP_PORT)) lmp_print(bp, slen); else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) || (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH)) rx_print(bp, slen, sport, dport); else if (dport == BFD_CONTROL_PORT || dport == BFD_ECHO_PORT ) bfd_print(bp, slen, dport); else if (ISPORT(NETBIOS_NS_PORT)) nbt_udp137_print(bp, slen); else if (ISPORT(NETBIOS_DGRAM_PORT)) nbt_udp138_print(bp, slen); else if (ISPORT(ISAKMP_PORT)) isakmp_print(bp, slen); else if (ISPORT(ISAKMP_PORT_NATT)) isakmp_rfc3948_print(bp, slen); else if (ISPORT(ISAKMP_PORT_USER1) || ISPORT(ISAKMP_PORT_USER2)) isakmp_print(bp, slen); else { int elen = 0; parser->eflag = ArgusThisEflag; elen = ArgusEncode (parser, (const char *)bp, NULL, slen, ArgusBuf, sizeof(ArgusBuf)); parser->eflag = ARGUS_HEXDUMP; } /* else if (ISPORT(3456)) vat_print(bp, slen); else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT)) zephyr_print(bp, slen); else if (ISPORT(RIPNG_PORT)) ripng_print(bp, slen); else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT)) dhcp6_print(bp, slen); else if (dport == 4567) wb_print(bp, slen); else if (ISPORT(CISCO_AUTORP_PORT)) cisco_autorp_print(bp, slen); else if (ISPORT(RADIUS_PORT) || ISPORT(RADIUS_NEW_PORT) || ISPORT(RADIUS_ACCOUNTING_PORT) || ISPORT(RADIUS_NEW_ACCOUNTING_PORT) ) radius_print(bp, slen); else if (dport == HSRP_PORT) hsrp_print(bp, slen); else if (ISPORT(LWRES_PORT)) lwres_print(bp, slen); else if (ISPORT(MPLS_LSP_PING_PORT)) lspping_print(bp, slen); */ } } } return (ArgusBuf); }