⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sock.cc

📁 南京航空航天大学开发的一个类Unix和Linux的操作系统,好不好看看就知道了,
💻 CC
字号:
#include <lib/root.h>#include <lib/errno.h>#include <mm/allockm.h>#include "pkt.h"#include "sock.h"#include <net/lib/if.h>#include <net/lib/route.h>#include <net/lib/sockios.h>#include <dev/net/dev.h>#include <net/inet/inet.h>#include <net/inet/route.h>#include <net/inet/debug.h>sock_t::sock_t(){	type = SOCKFD;	fdflags = FDREAD | FDWRITE;	backlog = 0;	solinger.on = 0;	solinger.seconds = 0;	soreuseaddr = 0;	sodebug = 0;	sokeepalive = 0;	sooobinline = 0;	sopriority = 0;	sobroadcast = 0;	maxsndbuf = cursndbuf = MAXSNDBUF;	maxrcvbuf = currcvbuf = MAXRCVBUF;}sock_t::~sock_t(){}static int ifreqioctl(int cmd, ulong arg){	ifreq_t *ifreq = (ifreq_t*) arg;	int e;	if (e = verw(ifreq, sizeof(ifreq_t)))		return e;	sockaddrin_t * sin = (sockaddrin_t*) &ifreq->u.addr;	sin->family = AFINET;	sin->port = 0;	netdev_t *netdev = findnetdev(ifreq->name);	if (!netdev)		return EINVAL;	switch (cmd) {	case SIOCGIFFLAGS:		ifreq->u.flags = netdev->flags;		break;	case SIOCSIFFLAGS:		netdev->flags = ifreq->u.flags;		break;	case SIOCGIFADDR:		sin->addr = netdev->praddr;		break;	case SIOCSIFADDR:		netdev->praddr = sin->addr;		break;	case SIOCGIFBRDADDR:		sin->addr = netdev->prbcastaddr;		break;	case SIOCSIFBRDADDR:		netdev->prbcastaddr = sin->addr;		break;	case SIOCGIFDSTADDR:		break;	case SIOCSIFDSTADDR:		break;	case SIOCGIFNETMASK:		sin->addr = netdev->netmask;		break;	case SIOCSIFNETMASK:		netdev->netmask = sin->addr;		break;	case SIOCGIFMETRIC:		ifreq->u.metric = netdev->metric;		break;	case SIOCSIFMETRIC:		netdev->metric = ifreq->u.metric;		break;	case SIOCGIFMTU:		ifreq->u.mtu = netdev->mtu;		break;	case SIOCSIFMTU:		netdev->mtu = ifreq->u.mtu;		break;	case SIOCGIFMEM:		break;	case SIOCSIFMEM:		break; 	case SIOCGIFHWADDR:		memcpy(ifreq->u.hwaddr.data, netdev->hwaddr, netdev->hwaddrlen);		break;	case SIOCSIFHWADDR:		memcpy(netdev->hwaddr, ifreq->u.data, netdev->hwaddrlen);		break;	}	return 0;}int ifconfioctl(int cmd, ulong arg){	ifconf_t *ifc = (ifconf_t*) arg;	int e;	if (e = verw(ifc, sizeof(ifconf_t)))		return e;	if (e = verw(ifc->u.buf, ifc->buflen))		return e;	int num = ifc->buflen / sizeof(ifreq_t);	ifreq_t *ifr = ifc->u.ifreq;	netdev_t *netdev;	foreach (netdev, netdevq) {		strcpy(ifr->name, netdev->name);		sockaddrin_t *sin = (sockaddrin_t*) &ifr->u.addr;		sin->family = AFINET;		sin->addr = netdev->praddr;		ifr++;		if (--num == 0)			break;	}	ifc->buflen = (char*)ifr - (char*)ifc->u.ifreq;	return 0;}static u32_t ip(sockaddr_t *sa){	return ((sockaddrin_t*)sa)->addr;}static int routeioctl(int cmd, ulong arg){	int e;	linuxrt_t * l = (linuxrt_t*) arg;	if (e = verw(l, sizeof(linuxrt_t)))		return e;	if (e = verrstr(l->dev))		return e;	netdev_t * netdev = findnetdev(l->dev);	if (cmd == SIOCADDRT)		addroute(l->flags, ip(&l->dstaddr), ip(&l->netmask), ip(&l->gateway), netdev);	else if (cmd == SIOCDELRT)		;//delroute(ip(&l->dstaddr));	return 0;}int sock_t::ioctl(int cmd, ulong arg){	if (cmd == SIOCGIFCONF)		return ifconfioctl(cmd, arg);	if (cmd == SIOCADDRT || cmd == SIOCDELRT)		return routeioctl(cmd, arg);	return ifreqioctl(cmd, arg);}int sock_t::read(void * buf, int count){	return recv(buf, count,  0);}int sock_t::write(void * buf, int count){	return send(buf, count,  0);}int sock_t::allocsndbuf(pkt_t **pp, int flags, int headlen, int datalen){	int roomlen = headlen + datalen;        /* if flags is AKERN, force allocation */	while (flags != AKERN && cursndbuf < roomlen) {		debug(TCPDBG, "wait for sndbuf\n");		WAIT(waitq);	}	*pp = newpkt(flags, headlen, datalen);	if (!*pp)		return ENOMEM;	cursndbuf -= roomlen;	return 0;}void sock_t::freesndbuf(pkt_t *p){	cursndbuf += p->roomlen();	waitq.broadcast();	delpkt(p);}int sock_t::allocrcvbuf(pkt_t *p){	if (currcvbuf < p->roomlen())		return ENOMEM;	currcvbuf -= p->roomlen();	return 0;}void sock_t::freercvbuf(pkt_t *p){	freercvbuf(p->roomlen());	delpkt(p);}/* set the SOL_SOCKET option */int sock_t::setsocketopt(int optname, void * optvalptr, socklen_t optlen){/* NOTE: memcpy(&optval, optval_, optlen) is not worked on the big-endian machine */	int optval = 0;#define GUESS(type) if (optlen == sizeof(type)) { optval = *(type*)optvalptr; }	GUESS(char) else GUESS(short) else GUESS(int);  	switch(optname) {		case SOTYPE:		case SOERROR:		case SODONTROUTE:			return 0;		case SOBROADCAST:			sobroadcast = optval;			return 0;		case SODEBUG:			if (!suser())				return EPERM;			sodebug = optval;		case SOSNDBUF:			maxsndbuf = minmax(MINSNDBUF, optval, MAXSNDBUF);			return 0;		case SORCVBUF:			maxrcvbuf = minmax(MINRCVBUF, optval, MAXRCVBUF);			return 0;		case SOREUSEADDR:			soreuseaddr = optval;			return 0;		case SOLINGER:			if (optlen != sizeof(linger_t))				return EINVAL;			solinger = *(linger_t*)optvalptr;			return 0;		case SOKEEPALIVE:			sokeepalive = optval;			return 0;	 	case SOOOBINLINE:			sooobinline = optval;			return 0;	        case SOPRIORITY:			sopriority = optval;			return 0;		default:		  	return(ENOPROTOOPT);  	}	return 0;}/* get the SOL_SOCKET option */int sock_t::getsocketopt(int optname, void * optvalptr, socklen_t * optlen){	int optval = 0;  	switch(optname) {		case SOERROR:		case SODONTROUTE:			return 0;		case SODEBUG:			optval = sodebug;			break;		case SOBROADCAST:			optval = sobroadcast;			break;		case SOLINGER: 			if (*optlen != sizeof(linger_t))				return EINVAL;			*(linger_t*)optvalptr = solinger;			return 0;		case SOSNDBUF:			optval = maxsndbuf;			break;		case SORCVBUF:			optval = maxrcvbuf;			break;		case SOREUSEADDR:			optval = soreuseaddr;			break;		case SOKEEPALIVE:			optval = sokeepalive;			break;		case SOTYPE:			/* optval = SOCKSTREAM */			break;		case SOOOBINLINE:			optval = sooobinline;			break;		case SOPRIORITY:			optval = sopriority;			break;		default:			return(ENOPROTOOPT);	}	if (*optlen != sizeof(int))		return EINVAL;	*optlen = sizeof(int);	*(int*)optvalptr = optval;  	return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -