示例#1
0
static int
secure_passwords()
{
	void           *d, *d1;
	int             status;
	ni_index        where;
	ni_id           dir;
	ni_namelist     nl;

	status = ni_open(NULL, ".", &d);
	while (status == NI_OK)
	{
		dir.nii_object = 0;
		status = ni_lookupprop(d, &dir, "security_options", &nl);
		if (status == NI_OK)
		{
			where = ni_namelist_match(nl, "secure_passwords");
			if (where != NI_INDEX_NULL)
			{
				ni_free(d);
				return 1;
			}
		}
		d1 = d;
		status = ni_open(d1, "..", &d);
		ni_free(d1);
	}

	return 0;
}
示例#2
0
static int
password_lifetime()
{
	void           *d, *d1;
	int             status;
	ni_id           dir;
	ni_namelist     nl;

	status = ni_open(NULL, ".", &d);
	while (status == NI_OK)
	{
		status = ni_pathsearch(d, &dir, "/users");
		if (status == NI_OK)
		{
			status = ni_lookupprop(d, &dir, "password_lifetime", &nl);
			if (status == NI_OK)
			{
				if (nl.ni_namelist_val[0] != NULL)
				{
					ni_free(d);
					/* free namelist? */
					return atoi(nl.ni_namelist_val[0]);
				}
			}
		}
		d1 = d;
		status = ni_open(d1, "..", &d);
		ni_free(d1);
	}

	return -1;
}
示例#3
0
int NetInfoPrefsSource::GetValueByIndex(const char* inKey, UInt32 inIndex, char* ioValue)
{
    ni_status status = NI_OK;
    ni_namelist nameList = {};
    void* localDomain = NULL;
    ni_id qtssDir = {}; 
    
    ioValue[0] = '\0';

    status = ni_open(NULL, ".", &localDomain);
    if (status != NI_OK)
        return false;
        
    if (status == NI_OK)
        status = ni_pathsearch(localDomain, &qtssDir, gQTSSPropertiesPath);
        
    if (status == NI_OK)
        status = ni_lookupprop(localDomain, &qtssDir, inKey, &nameList);

    if (status == NI_OK)
    {
        if (nameList.ni_namelist_len > inIndex)
            strcpy(ioValue, nameList.ni_namelist_val[inIndex]);
        else
            status = NI_BADID;
        ni_namelist_free(&nameList);
    }
    
    ni_free(localDomain);
    
    return (status == NI_OK);
}
示例#4
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_config_parse_file (krb5_context context,
			const char *fname,
			krb5_config_section **res)
{
    void *ni = NULL, *lastni = NULL;
    int i;
    ni_status nis;
    ni_id nid;
    ni_idlist children;

    krb5_config_section *s;
    int ret;

    s = NULL;

    for (i = 0; i < 256; i++) {
	if (i == 0) {
	    nis = ni_open(NULL, ".", &ni);
	} else {
	    if (lastni != NULL) ni_free(lastni);
	    lastni = ni;
	    nis = ni_open(lastni, "..", &ni);
	}
	if (nis != NI_OK)
	    break;
	nis = ni_pathsearch(ni, &nid, "/locations/kerberos");
	if (nis == NI_OK) {
	    nis = ni_children(ni, &nid, &children);
	    if (nis != NI_OK)
		break;
	    nis = ni_idlist2binding(ni, &children, &s);
	    break;
	}
    }

    if (ni != NULL) ni_free(ni);
    if (ni != lastni && lastni != NULL) ni_free(lastni);

    ret = (nis == NI_OK) ? 0 : -1;
    if (ret == 0) {
	*res = s;
    } else {
	*res = NULL;
    }
    return ret;
}
示例#5
0
void NetInfoPrefsSource::SetValueByIndex(char* inKey, char* inValue, UInt32 inIndex)
{
    void* localDomain = NULL;
    ni_status status = NI_OK;
    ni_namelist nameList = {};

    //ni_namelist_insert(&nameList, (char*)inValue, NI_INDEX_NULL);
    ni_namelist_insert(&nameList, inValue, inIndex);

    status = ni_open(NULL, ".", &localDomain);

    if (status == NI_OK)
    {
        //create the path if it doesn't already exist
        status = ni2_create(localDomain, gQTSSPropertiesPath);

        if (status == NI_OK)
            status = ni2_appendprop(localDomain, gQTSSPropertiesPath, inKey, nameList);
    }
    ni_namelist_free(&nameList);
    ni_free(localDomain);
}
示例#6
0
/*
 * Change a user's password in NetInfo.
 */
PAM_EXTERN
int 
pam_sm_chauthtok(pam_handle_t * pamh, int flags, int argc, const char **argv)
{
	char           *oldHash, *newHash;
	char           *oldPassword = NULL, *newPassword = NULL;
	void           *d;
	int             status, isroot, tries, maxTries;
	int		options = 0;
	int		amChangingExpiredPassword;
	ni_id           dir;
	ni_proplist     pl;
	ni_property     p;
	ni_namelist     nl;
	int             ni_uid, uid, secure, minlen, lifetime;
	ni_index        where;
	struct pam_conv *appconv;
	struct pam_message msg, *pmsg;
	struct pam_response *resp;
	const char     *cmiscptr = NULL;
	char           *uname;
	char            salt[9];
	int i;

	amChangingExpiredPassword = flags & PAM_CHANGE_EXPIRED_AUTHTOK;

	status = pam_get_item(pamh, PAM_CONV, (void **) &appconv);
	if (status != PAM_SUCCESS)
		return status;

	status = pam_get_item(pamh, PAM_USER, (void **) &uname);
	if (status != PAM_SUCCESS)
		return status;

	if (uname == NULL)
		return PAM_USER_UNKNOWN;

	status = pam_get_item(pamh, PAM_OLDAUTHTOK, (void **) &oldPassword);
	if (status != PAM_SUCCESS) {
		return status;
	}

	if (pam_test_option(&options, PAM_OPT_USE_FIRST_PASS, NULL) ||
	    pam_test_option(&options, PAM_OPT_TRY_FIRST_PASS, NULL))
	{
		if (pam_get_item(pamh, PAM_AUTHTOK, (void **) &newPassword) != PAM_SUCCESS)
			newPassword = NULL;

		if (pam_test_option(&options, PAM_OPT_USE_FIRST_PASS, NULL) && newPassword == NULL)
			return PAM_AUTHTOK_RECOVER_ERR;
	}
	d = domain_for_user(uname, NULL, &dir);
	if (d == (void *) NULL)
	{
		syslog(LOG_ERR, "user %s not found in NetInfo", uname);
		return PAM_USER_UNKNOWN;
	}

	/*
	 * These should be configurable in NetInfo.
	 */
	secure = secure_passwords();
	maxTries = secure ? 3 : 5;
	minlen = secure ? 8 : 5;

	/*
         * Read the passwd and uid from NetInfo.
         */
	status = ni_lookupprop(d, &dir, "passwd", &nl);
	if (status == NI_NOPROP)
		nl.ni_namelist_len = 0;
	else if (status != NI_OK)
	{
		ni_free(d);
		syslog(LOG_ERR, "NetInfo read failed: %s", ni_error(status));
		return netinfo2PamStatus(status);
	}
	oldHash = NULL;
	if (nl.ni_namelist_len > 0)
		oldHash = nl.ni_namelist_val[0];

	status = ni_lookupprop(d, &dir, "uid", &nl);
	if (status != NI_OK)
	{
		ni_free(d);
		syslog(LOG_ERR, "NetInfo read failed: %s", ni_error(status));
		return netinfo2PamStatus(status);
	}
	ni_uid = -2;
	if (nl.ni_namelist_len > 0)
		ni_uid = atoi(nl.ni_namelist_val[0]);

	/*
         * See if I'm uid 0 on the master host for the user's NetInfo domain.
         */
	isroot = is_root_on_master(d);
	uid = getuid();
	if (isroot)
	{
		if (flags & PAM_PRELIM_CHECK)
		{
			/* Don't need old password. */
			return PAM_SUCCESS;
		}
	}
	else if (uid != ni_uid)
	{
		ni_free(d);
		return PAM_PERM_DENIED;
	}

	if (flags & PAM_PRELIM_CHECK)
	{
		/*
		 * If we are not root, we should verify the old
		 * password.
		 */
		char           *encrypted;

		if (oldPassword != NULL &&
		   (pam_test_option(&options, PAM_OPT_USE_FIRST_PASS, NULL) ||
		    pam_test_option(&options, PAM_OPT_TRY_FIRST_PASS, NULL)))
		{
			encrypted = crypt(oldPassword, oldHash);

			if (oldPassword[0] == '\0' && oldHash != '\0')
				encrypted = ":";
			status = strcmp(encrypted, oldHash) == 0 ? PAM_SUCCESS : PAM_AUTH_ERR;
			if (status != PAM_SUCCESS)
			{
				if (pam_test_option(&options, PAM_OPT_USE_FIRST_PASS, NULL))
					sendConversationMessage(appconv, "NetInfo password incorrect", PAM_ERROR_MSG, &options);
				else
					sendConversationMessage(appconv, "NetInfo password incorrect: try again", PAM_ERROR_MSG, &options);
			}
			else
			{
				ni_free(d);
				return PAM_SUCCESS;
			}
		}
		tries = 0;

		while (oldPassword == NULL && tries++ < maxTries)
		{
			pmsg = &msg;
			msg.msg_style = PAM_PROMPT_ECHO_OFF;
			msg.msg = OLD_PASSWORD_PROMPT;
			resp = NULL;

			status = appconv->conv(1, (struct pam_message **) & pmsg, &resp, appconv->appdata_ptr);
			if (status != PAM_SUCCESS)
			{
				ni_free(d);
				return status;
			}
			oldPassword = resp->resp;
			free(resp);

			encrypted = crypt(oldPassword, oldHash);

			if (oldPassword[0] == '\0' && oldHash != '\0')
				encrypted = ":";

			status = strcmp(encrypted, oldHash) == 0 ? PAM_SUCCESS : PAM_AUTH_ERR;

			if (status != PAM_SUCCESS)
			{
				int             abortMe = 0;

				if (oldPassword != NULL && oldPassword[0] == '\0')
					abortMe = 1;

				_pam_overwrite(oldPassword);
				_pam_drop(oldPassword);

				if (!amChangingExpiredPassword & abortMe)
				{
					sendConversationMessage(appconv, "Password change aborted", PAM_ERROR_MSG, &options);
					ni_free(d);
					return PAM_AUTHTOK_RECOVER_ERR;
				}
				else
				{
					sendConversationMessage(appconv, "NetInfo password incorrect: try again", PAM_ERROR_MSG, &options);
				}
			}
		}

		if (oldPassword == NULL)
		{
			status = PAM_MAXTRIES;
		}
		(void) pam_set_item(pamh, PAM_OLDAUTHTOK, oldPassword);
		ni_free(d);

		return status;
	}			/* PAM_PRELIM_CHECK */

	status = PAM_ABORT;
	tries = 0;

	while (newPassword == NULL && tries++ < maxTries)
	{
		pmsg = &msg;
		msg.msg_style = PAM_PROMPT_ECHO_OFF;
		msg.msg = NEW_PASSWORD_PROMPT;
		resp = NULL;

		status = appconv->conv(1, &pmsg, &resp, appconv->appdata_ptr);
		if (status != PAM_SUCCESS)
		{
			ni_free(d);
			return status;
		}
		newPassword = resp->resp;
		free(resp);

		if (newPassword[0] == '\0')
		{
			free(newPassword);
			newPassword = NULL;
		}

		if (newPassword != NULL)
		{
			if (isroot == 0)
			{
				if (oldPassword != NULL && !strcmp(oldPassword, newPassword))
				{
					cmiscptr = "Passwords must differ";
					newPassword = NULL;
				}
				else if (strlen(newPassword) < minlen)
				{
					cmiscptr = "Password too short";
					newPassword = NULL;
				}
			}
		} else
		{
			ni_free(d);
			return PAM_AUTHTOK_RECOVER_ERR;
		}

		if (cmiscptr == NULL)
		{
			/* get password again */
			char           *miscptr;

			pmsg = &msg;
			msg.msg_style = PAM_PROMPT_ECHO_OFF;
			msg.msg = AGAIN_PASSWORD_PROMPT;
			resp = NULL;

			status = appconv->conv(1, &pmsg, &resp, appconv->appdata_ptr);

			if (status != PAM_SUCCESS)
			{
				ni_free(d);
				return status;
			}
			miscptr = resp->resp;
			free(resp);

			if (miscptr[0] == '\0')
			{
				free(miscptr);
				miscptr = NULL;
			}
			if (miscptr == NULL)
			{
				if (!amChangingExpiredPassword)
				{
					sendConversationMessage(appconv, "Password change aborted",
						    PAM_ERROR_MSG, &options);
					ni_free(d);
					return PAM_AUTHTOK_RECOVER_ERR;
				}
			}
			else if (!strcmp(newPassword, miscptr))
			{
				miscptr = NULL;
				break;
			}
			sendConversationMessage(appconv, "You must enter the same password",
						PAM_ERROR_MSG, &options);
			miscptr = NULL;
			newPassword = NULL;
		}
		else
		{
			sendConversationMessage(appconv, cmiscptr, PAM_ERROR_MSG, &options);
			cmiscptr = NULL;
			newPassword = NULL;
		}
	}

	if (cmiscptr != NULL || newPassword == NULL)
	{
		ni_free(d);
		return PAM_MAXTRIES;
	}
	/*
         * Lock onto the master server.
         */
	ni_needwrite(d, 1);

	/*
         * Authenticate if necessary
         */
	if (isroot == 0)
	{
		ni_setuser(d, uname);
		ni_setpassword(d, oldPassword);
	}
	/*
        * Create a random salt
        */
	srandom((int) time((time_t *) NULL));
	salt[0] = saltchars[random() % strlen(saltchars)];
	salt[1] = saltchars[random() % strlen(saltchars)];
	salt[2] = '\0';
	newHash = crypt(newPassword, salt);

	/*
         * Change the password in NetInfo.
         */
	status = ni_read(d, &dir, &pl);
	if (status != NI_OK)
	{
		ni_free(d);
		syslog(LOG_ERR, "NetInfo read failed: %s", ni_error(status));
		return netinfo2PamStatus(status);
	}
	p.nip_name = "passwd";
	p.nip_val.ni_namelist_len = 1;
	p.nip_val.ni_namelist_val = (ni_name *) malloc(sizeof(ni_name));
	p.nip_val.ni_namelist_val[0] = newHash;

	where = ni_proplist_match(pl, p.nip_name, NULL);
	if (where == NI_INDEX_NULL)
		status = ni_createprop(d, &dir, p, NI_INDEX_NULL);
	else
		status = ni_writeprop(d, &dir, where, p.nip_val);

	if (status != NI_OK)
	{
		ni_free(d);
		syslog(LOG_ERR, "NetInfo write property \"passwd\" failed: %s", ni_error(status));
		return netinfo2PamStatus(status);
	}

	/*
	 * Now, update "change" property. If this fails, we've still
	 * updated the password... perhaps the user should be alerted
	 * of this.
	 */
	lifetime = password_lifetime();
	if (lifetime > 0)
	{
		struct timeval tp;
		char change[64];

		where = ni_proplist_match(pl, "change", NULL);

		gettimeofday(&tp, NULL);
		tp.tv_sec += lifetime;

		snprintf(change, sizeof(change), "%ld", tp.tv_sec);

		p.nip_name = "change";
		p.nip_val.ni_namelist_len = 1;
		p.nip_val.ni_namelist_val[0] = change;

		if (where == NI_INDEX_NULL)
			status = ni_createprop(d, &dir, p, NI_INDEX_NULL);
		else
			status = ni_writeprop(d, &dir, where, p.nip_val);

		if (status != NI_OK)
		{
			ni_free(d);
			syslog(LOG_ERR, "NetInfo write property \"change\" failed: %s", ni_error(status));
			return netinfo2PamStatus(status);
		}
	}

	free(p.nip_val.ni_namelist_val);

	ni_free(d);

	/* tell lookupd to invalidate its cache */
	{
		int i, proc = -1;
		unit lookup_buf[MAX_INLINE_UNITS];
#ifdef __NeXT__
		port_t port;
#else
		mach_port_t port;
#endif

		port = _lookupd_port(0);
		(void) _lookup_link(port, "_invalidatecache", &proc);
		(void) _lookup_one(port, proc, NULL, 0, lookup_buf, &i);
	}

	return PAM_SUCCESS;
}
示例#7
0
static void    *
domain_for_user(char *uname, char *locn, ni_id * dir)
{
	char           *upath;
	int             status;
	void           *d, *d1;
	struct sockaddr_in server;
	char           *tag;
	int             bytag;

	if (uname == NULL)
		return NULL;

	/*
         * Find the user in NetInfo.
         */
	upath = malloc(8 + strlen(uname));
	sprintf(upath, "/users/%s", uname);

	if (locn != NULL)
	{
		bytag = 1;

		if (locn[0] == '/')
			bytag = 0;
		else if (!strncmp(locn, "./", 2))
			bytag = 0;
		else if (!strncmp(locn, "../", 3))
			bytag = 0;

		if (bytag == 1)
		{
			parse_server_tag(locn, &server, &tag);
			d = ni_connect(&server, tag);
			if (d == (void *) NULL)
				return (void *) NULL;
		} else
			status = ni_open(NULL, locn, &d);
		status = ni_pathsearch(d, dir, upath);
		free(upath);

		if (status == NI_OK)
			return d;

		ni_free(d);
		return (void *) NULL;
	}
	status = ni_open(NULL, ".", &d);
	while (status == NI_OK)
	{
		status = ni_pathsearch(d, dir, upath);
		if (status == NI_OK)
			break;
		d1 = d;
		status = ni_open(d1, "..", &d);
		ni_free(d1);
	}

	free(upath);

	if (status == NI_OK)
		return d;
	return (void *) NULL;
}
示例#8
0
void process(NetworkInterface* ni) {
	Packet* packet = ni_input(ni);
	if(!packet)
		return;
	if(arp_process(packet))
		return;
		
	Ether* ether = (Ether*)(packet->buffer + packet->start);
/*	
	if(endian16(ether->type) == ETHER_TYPE_ARP) {
		// ARP response
		ARP* arp = (ARP*)ether->payload;
		if(endian16(arp->operation) == 1 && endian32(arp->tpa) == address) {
			ether->dmac = ether->smac;
			ether->smac = endian48(ni->mac);
			arp->operation = endian16(2);
			arp->tha = arp->sha;
			arp->tpa = arp->spa;
			arp->sha = ether->smac;
			arp->spa = endian32(address);
			
			printf("- Ethernet Header -\n");
			printf("Dst Mac : %012lx Src Mac : %012lx\n Ether Type : %04hx\n", 
			endian48(ether->dmac), endian48(ether->smac), ether->type);

			ni_output(ni, packet);
			packet = NULL;
		}
	}*/
	if(endian16(ether->type) == ETHER_TYPE_IPv4) {
		IP* ip = (IP*)ether->payload;
		
		if(ip->protocol == IP_PROTOCOL_ICMP && endian32(ip->destination) == address){
			// Echo reply
			ICMP* icmp = (ICMP*)ip->body;
		
			// Performance check
//			perf();
	
			icmp->type = 0;
			icmp->checksum = 0;
			icmp->checksum = endian16(checksum(icmp, packet->end - packet->start - ETHER_LEN - IP_LEN));
			
			ip->destination = ip->source;
			ip->source = endian32(address);
			ip->ttl = endian8(64);
			ip->checksum = 0;
			ip->checksum = endian16(checksum(ip, ip->ihl * 4));
			
			ether->dmac = ether->smac;
			ether->smac = endian48(ni->mac);
			
			ni_output(ni, packet);
			packet = NULL;
		}
			/*
		} else if(ip->protocol == IP_PROTOCOL_TCP) {
			TCP* tcp = (TCP*)ip->body;
			
			printf("source=%u, destination=%u, sequence=%u, acknowledgement=%u\n", 
				endian16(tcp->source), endian16(tcp->destination), endian32(tcp->sequence), endian32(tcp->acknowledgement));
			printf("offset=%d, ns=%d, cwr=%d, ece=%d, urg=%d, ack=%d, psh=%d, rst=%d, syn=%d, fin=%d\n", 
				tcp->offset, tcp->ns, tcp->cwr, tcp->ece, tcp->urg, tcp->ack, tcp->psh, tcp->rst, tcp->syn, tcp->fin);
			printf("window=%d, checksum=%x, urgent=%d\n", endian16(tcp->window), endian16(tcp->checksum), endian16(tcp->urgent));
			*/
	}
	
	if(packet)
		ni_free(packet);
}
示例#9
0
void process(NetworkInterface* ni) {
	Packet* packet = ni_input(ni);

	if(!packet)
		return;
	if(arp_process(packet))
		return;
		
	Ether* ether = (Ether*)(packet->buffer + packet->start);

	if(endian16(ether->type) == ETHER_TYPE_IPv4) {
		IP* ip = (IP*)ether->payload;
		
		if(ip->protocol == IP_PROTOCOL_UDP) 
		{
			UDP* udp = (UDP*)ip->body;

			if(endian16(udp->destination) == SETKEY_PORT_NUM) 
			{
				int orig_len = endian16(ip->length);

				Parameter* parameter = (Parameter*)udp->body;

				// ARP Request
				if(arp_request(ni, parameter->dst_ip) == true);
					//printf("ARP Request for destination IP\n");

				int result = parse(parameter);

				memcpy(&(udp->body), &result, sizeof(result));
#ifdef _DEBUG_
				for(int i = 0; i < 64 /* Packet Minimum Size */ - ETHER_LEN /* 14 */ - IP_LEN /* 20 */ - UDP_LEN /* 8 */ - sizeof(result); i++)
					udp->body[i + 4] = i;
#endif

				uint16_t t = udp->destination;
				udp->destination = udp->source;
				udp->source = t;
				udp->checksum = 0;
				udp->length = endian16(64 - ETHER_LEN - IP_LEN);

				uint32_t t2 = ip->destination;
				ip->destination = ip->source;
				ip->source = t2;
				ip->ttl = 0x40;
				ip->length = endian16(64 - ETHER_LEN);
				ip->checksum = 0;
				ip->checksum = endian16(checksum(ip, ip->ihl * 4));

				uint64_t t3 = ether->dmac;
				ether->dmac = ether->smac;
				ether->smac = t3;

				packet->end += (endian16(ip->length) - orig_len);

				ni_output(ni, packet);
				packet = NULL;
			}
		}

		if(ip->protocol == IP_PROTOCOL_ESP){

			int orig_len = endian16(ip->length);
	
#ifdef _DEBUG_
			printf("Before Decryption - Packet : \n");
			for(int i = 1; i < 1 + endian16(ip->length); i++)
			{
				printf("%02x ", ether->payload[i - 1]); // Packet - IP Header 
				if( i % 16 == 0 )
					printf("\n");
			}
			printf("\n");
#endif	

			if(decrypt(ip) >= 0)
			{
				packet->end += (endian16(ip->length) - orig_len);

			//	ether->dmac = endian48(arp_get_mac(ni, endian32(ip->destination)));
			//	ether->smac = endian48(ni->mac);
						
#ifdef _DEBUG_
				printf("- Ethernet Header After Decryption-\n");
				printf("Dst Mac : %012lx Src Mac : %012lx\n Ether Type : %x\n", 
						endian48(ether->dmac), endian48(ether->smac), ether->type);
#endif		
				if(ip->protocol == IP_PROTOCOL_ICMP){
					// Echo reply
					ICMP* icmp = (ICMP*)ip->body;
					
					icmp->type = 0;
					icmp->checksum = 0;
					icmp->checksum = endian16(checksum(icmp, packet->end - packet->start - ETHER_LEN - IP_LEN));
					
					uint32_t temp = ip->destination;
					ip->destination = ip->source;
					ip->source = temp; 
					ip->ttl = endian8(64);
					ip->checksum = 0;
					ip->checksum = endian16(checksum(ip, ip->ihl * 4));
					
				//	ether->dmac = ether->smac;
				//	ether->smac = endian48(ni->mac);
					
				//	ni_output(ni, packet);
				//		packet = NULL;
				}

			//	ni_output(ni1, packet);
			//	packet = NULL;
			}
			
			orig_len = endian16(ip->length);

#ifdef _DEBUG_
			printf("Before Encryption - Packet : \n");
			for(int i = 1; i < 1 + endian16(ip->length); i++)
			{
				printf("%02x ", ether->payload[i - 1]); // Packet - IP Header 
				if( i % 16 == 0 )
					printf("\n");
			}
			printf("\n");
#endif 

			if(encrypt(ip) >= 0)
			{
				packet->end += (endian16(ip->length) - orig_len);
				ether->dmac = endian48(arp_get_mac(ni, endian32(ip->destination)));
				ether->smac = endian48(ni->mac);
#ifdef _DEBUG_		
				printf("- Ethernet Header After Encryption-\n");
				printf("Dst Mac : %012lx Src Mac : %012lx\n Ether Type : %x\n", 
						endian48(ether->dmac), endian48(ether->smac), ether->type);
				
#endif	
				ni_output(ni, packet);

				packet = NULL;
			}
		}
	}

	if(packet)
		ni_free(packet);
}