void CBgAnimHost::LoadPluginL() { User::LeaveIfError(iPluginLibrary.Load(*iCurrentPluginDllName)); plugingetinterfacefunc getif = (plugingetinterfacefunc)iPluginLibrary.Lookup(1); if (!getif) { iPluginLibrary.Close(); User::Leave(KErrNotFound); } iPlugin = (plugin_export_v1_t*) getif(1); TBuf8<256> pluginpath; pluginpath.Copy(*iCurrentPluginAssetDir); User::LeaveIfError(iPlugin->initialize((const char*)pluginpath.PtrZ(), KMaxGPUMemUsage)); iPlugin->setdisplaydimensions(iDisplaySize.iWidth, iDisplaySize.iHeight); if (iPlugin->desiredsensors && iPlugin->receivesensordata) { const unsigned int* sensors = iPlugin->desiredsensors(); while (*sensors) { CSensorListener* listener = NULL; TRAPD(serr, listener = CSensorListener::NewL(this, *sensors++)); if (!serr) { iSensorListeners.Append(listener); StartSensorsL(); } } } }
/* * Process BOOTREPLY packet. */ static void handle_reply(void) { struct bootp *bp = (struct bootp *) pktbuf; struct ifreq *ifr; struct sockaddr_in *sip; u_char canon_haddr[MAXHADDRLEN]; unsigned char *ha; int len; if (debug) { report(LOG_INFO, " reply for %s", inet_ntoa(bp->bp_yiaddr)); } /* Make sure client is directly accessible. */ ifr = getif(s, &(bp->bp_yiaddr)); if (!ifr) { report(LOG_NOTICE, "no interface for reply to %s", inet_ntoa(bp->bp_yiaddr)); return; } #if 1 /* Experimental (see BUG above) */ /* #ifdef CATER_TO_OLD_CLIENTS ? */ /* * The giaddr field has been set to our "default" IP address * which might not be on the same interface as the client. * In case the client looks at giaddr, (which it should not) * giaddr is now set to the address of the correct interface. */ sip = (struct sockaddr_in *) &(ifr->ifr_addr); bp->bp_giaddr = sip->sin_addr; #endif /* Set up socket address for send to client. */ clnt_addr.sin_family = AF_INET; clnt_addr.sin_addr = bp->bp_yiaddr; clnt_addr.sin_port = htons(bootpc_port); /* Create an ARP cache entry for the client. */ ha = bp->bp_chaddr; len = bp->bp_hlen; if (len > MAXHADDRLEN) len = MAXHADDRLEN; if (bp->bp_htype == HTYPE_IEEE802) { haddr_conv802(ha, canon_haddr, len); ha = canon_haddr; } if (debug > 1) report(LOG_INFO, "setarp %s - %s", inet_ntoa(bp->bp_yiaddr), haddrtoa(ha, len)); setarp(s, &bp->bp_yiaddr, ha, len); /* Send reply with same size packet as request used. */ if (sendto(s, pktbuf, pktlen, 0, (struct sockaddr *) &clnt_addr, sizeof(clnt_addr)) < 0) { report(LOG_ERR, "sendto: %s", get_network_errmsg()); } }
/* * get MIB-II statistics. It maintaines a simple cache which buffers the last * read block of MIB statistics (which may contain the whole table). It calls * *comp to compare every entry with an entry pointed by arg. *comp should * return 0 if comparison is successful. Req_type may be GET_FIRST, GET_EXACT, * GET_NEXT. If search is successful getMibstat returns 0, otherwise 1. */ int getMibstat(mibgroup_e grid, void *resp, size_t entrysize, req_e req_type, int (*comp) (void *, void *), void *arg) { int ret, rc = -1, mibgr, mibtb, cache_valid; size_t length; mibcache *cachep; found_e result = NOT_FOUND; void *ep; /* * We assume that Mibcache is initialized in mibgroup_e enum order so we * don't check the validity of index here. */ DEBUGMSGTL(("kernel_sunos5", "getMibstat (%d, *, %d, %d, *, *)\n", grid, entrysize, req_type)); cachep = &Mibcache[grid]; mibgr = Mibmap[grid].group; mibtb = Mibmap[grid].table; if (cachep->cache_addr == (void *) -1) /* Hasn't been initialized yet */ init_mibcache_element(cachep); if (cachep->cache_size == 0) { /* Memory allocation problems */ cachep->cache_addr = resp; /* So use caller supplied address instead of cache */ cachep->cache_size = entrysize; cachep->cache_last_found = 0; } if (req_type != GET_NEXT) cachep->cache_last_found = 0; cache_valid = (cachep->cache_time > 0); DEBUGMSGTL(("kernel_sunos5","... cache_valid %d time %ld ttl %d now %ld\n", cache_valid, cachep->cache_time, cachep->cache_ttl, time(NULL))); if (cache_valid) { /* * Is it really? */ if (cachep->cache_comp != (void *)comp || cachep->cache_arg != arg) { cache_valid = 0; /* Nope. */ } } if (cache_valid) { /* * Entry is valid, let's try to find a match */ if (req_type == GET_NEXT) { result = getentry(req_type, (void *)((char *)cachep->cache_addr + (cachep->cache_last_found * entrysize)), cachep->cache_length - (cachep->cache_last_found * entrysize), entrysize, &ep, comp, arg); } else { result = getentry(req_type, cachep->cache_addr, cachep->cache_length, entrysize, &ep, comp, arg); } } if ((cache_valid == 0) || (result == NOT_FOUND) || (result == NEED_NEXT && cachep->cache_flags & CACHE_MOREDATA)) { /* * Either the cache is old, or we haven't found anything, or need the * next item which hasn't been read yet. In any case, fill the cache * up and try to find our entry. */ if (grid == MIB_INTERFACES) { rc = getif((mib2_ifEntry_t *) cachep->cache_addr, cachep->cache_size, req_type, (mib2_ifEntry_t *) & ep, &length, comp, arg); } else { rc = getmib(mibgr, mibtb, cachep->cache_addr, cachep->cache_size, entrysize, req_type, &ep, &length, comp, arg); } if (rc >= 0) { /* Cache has been filled up */ cachep->cache_time = cachep->cache_ttl; cachep->cache_length = length; if (rc == 1) /* Found but there are more unread data */ cachep->cache_flags |= CACHE_MOREDATA; else cachep->cache_flags &= ~CACHE_MOREDATA; cachep->cache_comp = (void *) comp; cachep->cache_arg = arg; } else { cachep->cache_comp = NULL; cachep->cache_arg = NULL; } } DEBUGMSGTL(("kernel_sunos5", "... result %d rc %d\n", result, rc)); if (result == FOUND || rc == 0 || rc == 1) { /* * Entry has been found, deliver it */ if (resp != NULL) { memcpy(resp, ep, entrysize); } ret = 0; cachep->cache_last_found = ((char *)ep - (char *)cachep->cache_addr) / entrysize; } else { ret = 1; /* Not found */ } DEBUGMSGTL(("kernel_sunos5", "... getMibstat returns %d\n", ret)); return ret; }
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); }
/* * Process BOOTREQUEST packet. * * Note, this just forwards the request to a real server. */ static void handle_request(void) { struct bootp *bp = (struct bootp *) pktbuf; #if 0 struct ifreq *ifr; #endif u_short secs, hops; /* XXX - SLIP init: Set bp_ciaddr = clnt_addr here? */ if (debug) { report(LOG_INFO, "request from %s", inet_ntoa(clnt_addr.sin_addr)); } /* Has the client been waiting long enough? */ secs = ntohs(bp->bp_secs); if (secs < minwait) return; /* Has this packet hopped too many times? */ hops = ntohs(bp->bp_hops); if (++hops > maxhops) { report(LOG_NOTICE, "request from %s reached hop limit", inet_ntoa(clnt_addr.sin_addr)); return; } bp->bp_hops = htons(hops); /* * Here one might discard a request from the same subnet as the * real server, but we can assume that the real server will send * a reply to the client before it waits for minwait seconds. */ /* If gateway address is not set, put in local interface addr. */ if (bp->bp_giaddr.s_addr == 0) { #if 0 /* BUG */ struct sockaddr_in *sip; /* * XXX - This picks the wrong interface when the receive addr * is the broadcast address. There is no portable way to * find out which interface a broadcast was received on. -gwr * (Thanks to <*****@*****.**> for finding this bug!) */ ifr = getif(s, &clnt_addr.sin_addr); if (!ifr) { report(LOG_NOTICE, "no interface for request from %s", inet_ntoa(clnt_addr.sin_addr)); return; } sip = (struct sockaddr_in *) &(ifr->ifr_addr); bp->bp_giaddr = sip->sin_addr; #else /* BUG */ /* * XXX - Just set "giaddr" to our "official" IP address. * RFC 1532 says giaddr MUST be set to the address of the * interface on which the request was received. Setting * it to our "default" IP address is not strictly correct, * but is good enough to allow the real BOOTP server to * get the reply back here. Then, before we forward the * reply to the client, the giaddr field is corrected. * (In case the client uses giaddr, which it should not.) * See handle_reply() */ bp->bp_giaddr = my_ip_addr; #endif /* BUG */ /* * XXX - DHCP says to insert a subnet mask option into the * options area of the request (if vendor magic == std). */ } /* Set up socket address for send. */ serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(bootps_port); /* Send reply with same size packet as request used. */ if (sendto(s, pktbuf, pktlen, 0, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { report(LOG_ERR, "sendto: %s", get_network_errmsg()); } }