1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
45:
46: 47: 48: 49:
50:
51: #include <tk/tkernel.h>
52:
53: #include <t2ex/socket.h>
54: #include <device/netdrv.h>
55:
56: #include <strings.h>
57:
58: #include "util.h"
59:
60: int net_random(void)
61: {
62: SYSTIM tim;
63: tk_get_tim(&tim);
64: return tim.hi ^ tim.lo ^ 0x21274a1dU;
65: }
66:
67: unsigned short checksum2(unsigned short *buf, int bufsz, unsigned long initial)
68: {
69: unsigned long sum = initial;
70:
71: while (bufsz > 1) {
72: sum += *buf;
73: buf++;
74: bufsz -= 2;
75: }
76:
77: if (bufsz == 1) {
78: sum += *(unsigned char *)buf;
79: }
80:
81: sum = (sum & 0xffff) + (sum >> 16);
82: sum = (sum & 0xffff) + (sum >> 16);
83:
84: return ~sum;
85: }
86:
87: unsigned short checksum(unsigned short *buf, int bufsz)
88: {
89: return checksum2(buf, bufsz, 0);
90: }
91:
92: int get_hwaddr(const char* ifname, char* buf)
93: {
94: struct ifaddrs* ifa_list;
95: struct ifaddrs* ifa;
96: struct sockaddr_dl* dl;
97: ER re;
98: char b[2048];
99:
100: re = so_getifaddrs(&ifa_list, b, sizeof b);
101: if ( re < 0 ) {
102: return re;
103: }
104: for(ifa = ifa_list; ifa != NULL; ifa = ifa->ifa_next) {
105: dl = (struct sockaddr_dl*)ifa->ifa_addr;
106: if (dl->sdl_family == AF_LINK && dl->sdl_type == IFT_ETHER) {
107: if ( strncmp(ifname, dl->sdl_data, dl->sdl_nlen) == 0 ) {
108: memcpy(buf, LLADDR(dl), 6);
109: return 0;
110: }
111: }
112: }
113:
114: return EX_NOENT;
115: }
116:
117: int if_updown(const char* ifname, int is_up)
118: {
119: int re;
120: int sd;
121: struct ifreq ifr;
122:
123: strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
124:
125: sd = so_socket(AF_INET, SOCK_DGRAM, 0);
126:
127: re = so_ioctl(sd, SIOCGIFFLAGS, &ifr);
128: DEBUG_PRINT(("if_updown: so_ioctl = %d(%d, %d)\n", re, MERCD(re), SERCD(re)));
129: if ( re < 0 ) {
130: so_close(sd);
131: return re;
132: }
133:
134: if ( is_up ) {
135: ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
136: } else {
137: ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
138: }
139:
140: re = so_ioctl(sd, SIOCSIFFLAGS, &ifr);
141: DEBUG_PRINT(("if_updown: so_ioctl = %d(%d, %d)\n", re, MERCD(re), SERCD(re)));
142: if ( re < 0 ) {
143: so_close(sd);
144: return re;
145: }
146:
147: so_close(sd);
148:
149: return 0;
150: }
151:
152: void set_ifaddr(const char* ifname, in_addr_t addr, in_addr_t mask)
153: {
154: int sd;
155: int iore;
156: struct ifreq ifr;
157: struct sockaddr_in* p_iosa;
158:
159: sd = so_socket(AF_INET, SOCK_DGRAM, 0);
160: DEBUG_PRINT(("set_ifaddr: so_socket = %d(%d, %d)\n", sd, MERCD(sd), SERCD(sd)));
161:
162: bzero(&ifr, sizeof ifr);
163: p_iosa = (struct sockaddr_in*)&ifr.ifr_addr;
164: p_iosa->sin_len = sizeof *p_iosa;
165: p_iosa->sin_family = AF_INET;
166: p_iosa->sin_addr.s_addr = addr;
167: strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
168: iore = so_ioctl(sd, SIOCSIFADDR, &ifr);
169: DEBUG_PRINT(("set_ifaddr: so_ioctl = %d(%d, %d)\n", iore, MERCD(iore), SERCD(iore)));
170:
171: if ( mask ) {
172: bzero(&ifr, sizeof ifr);
173: p_iosa = (struct sockaddr_in*)&ifr.ifr_addr;
174: p_iosa->sin_len = sizeof *p_iosa;
175: p_iosa->sin_family = AF_INET;
176: p_iosa->sin_addr.s_addr = mask;
177: strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
178: iore = so_ioctl(sd, SIOCSIFNETMASK, &ifr);
179: DEBUG_PRINT(("set_ifaddr: so_ioctl = %d(%d, %d)\n", iore, MERCD(iore), SERCD(iore)));
180: }
181:
182: so_close(sd);
183: }
184:
185: void add_hosttable(const char* hostname, in_addr_t addr)
186: {
187: int re;
188: struct hosttable ht;
189: struct sockaddr_in sa;
190:
191: bzero(&sa, sizeof sa);
192: sa.sin_len = sizeof sa;
193: sa.sin_family = AF_INET;
194: sa.sin_addr.s_addr = addr;
195: bzero(&ht, sizeof ht);
196: ht.addr = (struct sockaddr*)&sa;
197: ht.host = (char*)hostname;
198:
199: re = so_resctl(SO_RES_ADD_TABLE, &ht, sizeof ht);
200: DEBUG_PRINT(("so_resctl(localhost) = %d(%d, %d)\n", re, MERCD(re), SERCD(re)));
201: }
202:
203: in_addr_t resolv_host(const char* host)
204: {
205: int re;
206: struct addrinfo hints;
207: struct addrinfo* res;
208: char buf[512];
209:
210: bzero(&hints, sizeof hints);
211: hints.ai_family = AF_INET;
212: hints.ai_socktype = SOCK_STREAM;
213:
214: re = so_getaddrinfo(host, NULL, &hints, &res, buf, sizeof buf, NULL);
215: DEBUG_PRINT(("resolv_host: so_getaddrinfo = %d(%d, %d)\n", re, MERCD(re), SERCD(re)));
216: if ( re < 0 ) {
217: return INADDR_NONE;
218: }
219:
220: if ( res != NULL ) {
221: return ((struct sockaddr_in*)res->ai_addr)->sin_addr.s_addr;
222: }
223:
224: return INADDR_NONE;
225: }
226:
227: void netdrv_set_minpktsz(const char* ifname, W minsz)
228: {
229: ID dd;
230: W len;
231: NetRxBufSz bufsz;
232: ER ercd;
233:
234: dd = tk_opn_dev((UB*)ifname, TD_UPDATE);
235: if (dd < 0) {
236: return;
237: }
238:
239: ercd = tk_srea_dev(dd, DN_NETRXBUFSZ, &bufsz, sizeof(bufsz), &len);
240: if (ercd == E_OK) {
241: bufsz.minsz = minsz;
242: tk_swri_dev(dd, DN_NETRXBUFSZ, &bufsz, sizeof(bufsz), &len);
243: }
244:
245: tk_cls_dev(dd, 0);
246: }