home *** CD-ROM | disk | FTP | other *** search
- #include "services.h"
-
- extern struct ops o;
- static int services_initialized = 0;
- static int numtcpports = 0;
- static int numudpports = 0;
- static struct service_list *service_table[SERVICE_TABLE_SIZE];
-
- static int nmap_services_init() {
- char filename[512];
- FILE *fp;
- char servicename[128], proto[16];
- unsigned short portno;
- char *p;
- char line[1024];
- int lineno = 0;
- struct service_list *current, *previous;
- int res;
-
- if (nmap_fetchfile(filename, sizeof(filename), "nmap-services") == -1) {
- error("Unable to find nmap-services! Resorting to /etc/services");
- strcpy(filename, "/etc/services");
- }
-
- fp = fopen(filename, "r");
- if (!fp) {
- fatal("Unable to open %s for reading service information", filename);
- }
-
- bzero(service_table, sizeof(service_table));
-
- while(fgets(line, sizeof(line), fp)) {
- lineno++;
- p = line;
- res = sscanf(line, "%s %hu/%s", servicename, &portno, proto);
- if (res !=3)
- continue;
- portno = htons(portno);
-
- /* Now we make sure our services doesn't have duplicates */
- for(current = service_table[portno % SERVICE_TABLE_SIZE], previous = NULL;
- current; current = current->next) {
- if (portno == current->servent->s_port &&
- strcasecmp(proto, current->servent->s_proto) == 0) {
- if (o.debugging) {
- error("Port %d proto %s is duplicated in services file %s", ntohs(portno), proto, filename);
- }
- break;
- }
- previous = current;
- }
- if (current)
- continue;
-
- if (strncasecmp(proto, "tcp", 3) == 0) {
- numtcpports++;
- } else if (strncasecmp(proto, "udp", 3) == 0) {
- numudpports++;
- } else if (strncasecmp(proto, "ddp", 3) == 0) {
- /* ddp is some apple thing...we don't "do" that */
- } else if (strncasecmp(proto, "divert", 6) == 0) {
- /* divert sockets are for freebsd's natd */
- } else if (strncasecmp(proto, "#", 1) == 0) {
- /* possibly misplaced comment, but who cares? */
- } else {
- if (o.debugging)
- error("Unknown protocol (%s) on line %d of services file %s.", proto, lineno, filename);
- continue;
- }
-
- current = (struct service_list *) cp_alloc(sizeof(struct service_list));
- current->servent = (struct servent *) cp_alloc(sizeof(struct servent));
- current->next = NULL;
- if (previous == NULL) {
- service_table[portno % SERVICE_TABLE_SIZE] = current;
- } else {
- previous->next = current;
- }
- current->servent->s_name = cp_strdup(servicename);
- current->servent->s_port = portno;
- current->servent->s_proto = cp_strdup(proto);
- current->servent->s_aliases = NULL;
- }
- fclose(fp);
- services_initialized = 1;
- return 0;
- }
-
-
- struct servent *nmap_getservbyport(int port, const char *proto) {
- struct service_list *current;
-
- if (!services_initialized)
- if (nmap_services_init() == -1)
- return NULL;
-
- for(current = service_table[port % SERVICE_TABLE_SIZE];
- current; current = current->next) {
- if (htons(port) == htons(current->servent->s_port) &&
- strcmp(proto, current->servent->s_proto) == 0)
- return current->servent;
- }
-
- /* Couldn't find it ... oh well. */
- return NULL;
-
- }
-
- /* Be default we do all ports 1-1024 as well as any higher ports
- that are in /etc/services. */
- unsigned short *getdefaultports(int tcpscan, int udpscan) {
- int portindex = 0;
- unsigned short *ports;
- char usedports[65536];
- struct service_list *current;
- int bucket;
- int portsneeded = 1; /* the 1 is for the terminating 0 */
-
- if (!services_initialized)
- if (nmap_services_init() == -1)
- fatal("Getfastports: Coudn't get port numbers");
-
- bzero(usedports, sizeof(usedports));
- for(bucket = 1; bucket < 1025; bucket++) {
- usedports[bucket] = 1;
- portsneeded++;
- }
-
- for(bucket = 0; bucket < SERVICE_TABLE_SIZE; bucket++) {
- for(current = service_table[bucket % SERVICE_TABLE_SIZE];
- current; current = current->next) {
- if (!usedports[ntohs(current->servent->s_port)] &&
- ((tcpscan && !strncmp(current->servent->s_proto, "tcp", 3)) ||
- (udpscan && !strncmp(current->servent->s_proto, "udp", 3)))) {
- usedports[ntohs(current->servent->s_port)] = 1;
- portsneeded++;
- }
- }
- }
-
- ports = (unsigned short *) cp_alloc(portsneeded * sizeof(unsigned short));
- o.numports = portsneeded - 1;
-
- for(bucket = 1; bucket < 65536; bucket++) {
- if (usedports[bucket])
- ports[portindex++] = bucket;
- }
- ports[portindex] = 0;
-
- return ports;
-
- }
-
- unsigned short *getfastports(int tcpscan, int udpscan) {
- int portindex = 0;
- unsigned short *ports;
- char usedports[65536];
- struct service_list *current;
- int bucket;
- int portsneeded = 1; /* the 1 is for the terminating 0 */
-
- if (!services_initialized)
- if (nmap_services_init() == -1)
- fatal("Getfastports: Coudn't get port numbers");
-
- bzero(usedports, sizeof(usedports));
-
- for(bucket = 0; bucket < SERVICE_TABLE_SIZE; bucket++) {
- for(current = service_table[bucket % SERVICE_TABLE_SIZE];
- current; current = current->next) {
- if (!usedports[ntohs(current->servent->s_port)] &&
- ((tcpscan && !strncmp(current->servent->s_proto, "tcp", 3)) ||
- (udpscan && !strncmp(current->servent->s_proto, "udp", 3)))) {
- usedports[ntohs(current->servent->s_port)] = 1;
- portsneeded++;
- }
- }
- }
-
- ports = (unsigned short *) cp_alloc(portsneeded * sizeof(unsigned short));
- o.numports = portsneeded - 1;
-
- for(bucket = 1; bucket < 65536; bucket++) {
- if (usedports[bucket])
- ports[portindex++] = bucket;
- }
- ports[portindex] = 0;
-
- return ports;
- }
-
-
-
-
-
-