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

📄 torawsocket.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
// -*- mode: c++; c-basic-offset: 2 -*-/* * torawsocket.{cc,hh} -- element write data to socket * Mark Huang <mlhuang@cs.princeton.edu> * * Copyright (c) 2004  The Trustees of Princeton University (Trustees). * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <click/error.hh>#include <click/confparse.hh>#include <click/glue.hh>#include <click/router.hh>#include <click/standard/scheduleinfo.hh>#include <click/packet_anno.hh>#include <click/packet.hh>#include <clicknet/ip.h>#include <clicknet/udp.h>#include <clicknet/icmp.h>#include <unistd.h>#include <sys/socket.h>#include <arpa/inet.h>#include <fcntl.h>#include "fromrawsocket.hh"#include "torawsocket.hh"CLICK_DECLSToRawSocket::ToRawSocket()  : Element(1, 0), _task(this), _fd(-1){}ToRawSocket::~ToRawSocket(){}voidToRawSocket::notify_noutputs(int n){  set_noutputs(n <= 1 ? n : 1);}intToRawSocket::configure(Vector<String> &conf, ErrorHandler *errh){  String socktype;  if (cp_va_parse(conf, this, errh,		  cpString, "type of socket (`TCP', `UDP', `GRE', `ICMP')", &socktype,		  cpUnsignedShort, "port number", &_port,		  cpIgnoreRest,		  cpEnd) < 0)    return -1;  socktype = socktype.upper();  if (socktype == "TCP")    _protocol = IPPROTO_TCP;  else if (socktype == "UDP")    _protocol = IPPROTO_UDP;  else if (socktype == "GRE")    _protocol = IPPROTO_GRE;  else if (socktype == "ICMP")    _protocol = IPPROTO_ICMP;  else    return errh->error("unknown socket type `%s'", socktype.cc());  return 0;}intToRawSocket::initialize_socket_error(ErrorHandler *errh, const char *syscall){  int e = errno;		// preserve errno  if (_my_fd && _fd >= 0)    close(_fd);  _fd = -1;  return errh->error("%s: %s", syscall, strerror(e));}intToRawSocket::initialize(ErrorHandler *errh){  struct sockaddr_in sin;  // find a FromRawSocket and reuse its socket if possible  click_chatter("%s: looking for a FromRawSocket(%d, %d)\n", declaration().cc(), _protocol, _port);  for (int ei = 0; ei < router()->nelements() && _fd < 0; ei++) {    Element *e = router()->element(ei);    FromRawSocket *frs = (FromRawSocket *)e->cast("FromRawSocket");    if (frs && frs->protocol() == _protocol && frs->port() == _port) {      click_chatter("%s: found a FromRawSocket(%d, %d)\n", declaration().cc(), _protocol, _port);      _fd = frs->fd();      _my_fd = false;    }  }  // open socket, set options, bind to address  if (_fd < 0) {    _fd = socket(PF_INET, SOCK_RAW, _protocol);    if (_fd < 0)      return initialize_socket_error(errh, "socket");    _my_fd = true;    memset(&sin, 0, sizeof(sin));    sin.sin_family = PF_INET;    sin.sin_port = htons(_port);    sin.sin_addr = inet_makeaddr(0, 0);    // bind to port    if (bind(_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)      return initialize_socket_error(errh, "bind");  }  // include IP header  int one = 1;  if (setsockopt(_fd, 0, IP_HDRINCL, &one, sizeof(one)) < 0)    return initialize_socket_error(errh, "IP_HDRINCL");  if (input_is_pull(0)) {    ScheduleInfo::join_scheduler(this, &_task, errh);    _signal = Notifier::upstream_empty_signal(this, 0, &_task);  }  return 0;}voidToRawSocket::cleanup(CleanupStage){  if (_my_fd && _fd >= 0)    close(_fd);  _fd = -1;}voidToRawSocket::send_packet(Packet *p){  int w = 0;  const click_ip *ip = (const click_ip *) p->data();  const click_udp *udp = (const click_udp *) &ip[1];  const click_icmp_sequenced *icmp = (const click_icmp_sequenced *) &ip[1];  // const click_gre *gre = (const click_gre *) &ip[1];  // const click_pptp *pptp = (const click_pptp *) &ip[1];  struct sockaddr_in sin;  // cast to int so very large plen is interpreted as negative   if ((int)p->length() < (int)sizeof(click_ip)) {    click_chatter("%s: runt IP packet (%d bytes)", declaration().cc(), p->length());    goto done;  }  memset(&sin, 0, sizeof(sin));  sin.sin_family = PF_INET;  sin.sin_addr = ip->ip_dst;  switch (ip->ip_p) {  case IPPROTO_TCP:  case IPPROTO_UDP:    if ((int)p->length() < (int)sizeof(click_ip) + (int)sizeof(click_udp)) {      click_chatter("%s: runt %s packet (%d bytes)", declaration().cc(),		    ip->ip_p == IPPROTO_TCP ? "TCP" : "UDP", p->length());      goto done;    }    sin.sin_port = udp->uh_dport;    break;  case IPPROTO_ICMP:    if ((int)p->length() < (int)sizeof(click_ip) + (int)sizeof(click_icmp_sequenced)) {      click_chatter("%s: runt ICMP packet (%d bytes)", declaration().cc(), p->length());      goto done;    }    sin.sin_port = icmp->icmp_identifier;    break;  case IPPROTO_GRE:    // XXX handle GRE keys/PPTP call IDs  default:    click_chatter("%s: unhandled raw IP protocol %d", declaration().cc(), ip->ip_p);    goto done;  }  while (p->length()) {    w = sendto(_fd, p->data(), p->length(), 0, (const struct sockaddr*)&sin, sizeof(sin));    if (w < 0 && errno != EINTR)      break;    p->pull(w);  }  if (w < 0) {    click_chatter("%s: sendto: %s", declaration().cc(), strerror(errno));    checked_output_push(0, p);    return;  } done:    p->kill();}voidToRawSocket::push(int, Packet *p){  send_packet(p);}boolToRawSocket::run_task(){  // XXX reduce tickets when idle  Packet *p = input(0).pull();  if (p)    send_packet(p);  else if (!_signal)    return false;  _task.fast_reschedule();  return p != 0;}voidToRawSocket::add_handlers(){  if (input_is_pull(0))    add_task_handlers(&_task);}CLICK_ENDDECLSELEMENT_REQUIRES(userlevel linux)EXPORT_ELEMENT(ToRawSocket)

⌨️ 快捷键说明

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